软考程序员数据结构笔记Word下载.docx

上传人:b****4 文档编号:17004227 上传时间:2022-11-27 格式:DOCX 页数:35 大小:34.16KB
下载 相关 举报
软考程序员数据结构笔记Word下载.docx_第1页
第1页 / 共35页
软考程序员数据结构笔记Word下载.docx_第2页
第2页 / 共35页
软考程序员数据结构笔记Word下载.docx_第3页
第3页 / 共35页
软考程序员数据结构笔记Word下载.docx_第4页
第4页 / 共35页
软考程序员数据结构笔记Word下载.docx_第5页
第5页 / 共35页
点击查看更多>>
下载资源
资源描述

软考程序员数据结构笔记Word下载.docx

《软考程序员数据结构笔记Word下载.docx》由会员分享,可在线阅读,更多相关《软考程序员数据结构笔记Word下载.docx(35页珍藏版)》请在冰豆网上搜索。

软考程序员数据结构笔记Word下载.docx

模式匹配

字符串相加

求子串

(i,j)<

=>

注意:

不同矩阵所用的公式不同;

稀疏矩阵的转置(两种方式,后种为妙)

和数组有关的算法 

--------------------------------------------------------------------------------

  例程:

求两个长整数之和。

  a=13056952168

  b=87081299

  数组:

  a[]:

8

  b[]:

  由于以上的结构不够直观(一般越是直观越容易解决)将其改为:

11 86125965031a[0]=11(位数)

8 99218078000b[0]=8

  c进位 01100111100

  c[]:

11 76433044231c[0]的值(C位数)由c[max_s+1]决定!

  注意:

在求C前应该将C(max_s+1)位赋0.否则为随机数;

较小的整数高位赋0.

  算法:

已知a,b两个长整数,结果:

c=a+b;

  总共相加次数:

max_s=max(a[],b[])

  程序:

  for(i=1;

i<

=max_s;

i++){

   k=a[i]+b[i]+c[i];

   c[i]=k%10;

   c[i+1]=k/10;

  }

  求c位数:

  if(c[max_s+1]==0)

   c[0]=max_s;

  else

   c[0]=max_s+1;

  以下代码是我编的(毕竟是初学者.不太简洁大家不要见怪!

):

  /*两长整数相加*/

  #include<

stdio.h>

string.h>

  #definePRINprintf("

"

);

  intflag=0;

/*a[0]>

b[0]?

1:

0*/

  /*max(a[],b[]){}*/

  change(charda[],chardb[],inta[],intb[],intc[]){

   inti;

   if(a[0]>

b[0]){

    for(i=1;

=a[0];

a[i]=da[a[0]-i]-'

0'

i++);

/*a[0]-'

sogood!

*/

=b[0];

b[i]=db[b[0]-i]-'

    for(i=b[0]+1;

b[i]=0,i++);

=a[0]+1;

c[i]=0,i++);

    flag=1;

   }

   else{

    for(i=a[0]+1;

a[i]=0,i++);

=b[0]+1;

  add(inta[],intb[],intc[]){

   inti,sum;

   if(flag==1){

     sum=a[i]+b[i]+c[i];

     c[i+1]=sum/10;

     c[i]=sum%10;

    }

    if(c[a[0]+1]==0)

     c[0]=a[0];

    else

     c[0]=a[0]+1;

    if(c[b[0]+1]==0)

     c[0]=b[0];

     c[0]=b[0]+1;

  voidprint(intm[]){

   for(i=m[0];

i>

=1;

i--)

    printf("

%d,"

m[i]);

PRIN

  main(){

   ints;

   inta[20],b[20],c[20];

   charda[]={"

123456789"

};

   chardb[]={"

12344443"

   a[0]=strlen(da);

   b[0]=strlen(db);

   printf("

a[0]=%d"

a[0]);

b[0]=%d"

b[0]);

change(da,db,a,b,c);

flag=%d"

flag);

-----------------"

    print(a);

    s=abs(a[0]-b[0]);

+"

     for(s=s*2-1;

s>

0;

s--)

      printf("

      print(b);

    for(s=s*2-1;

     printf("

     print(a);

     print(b);

   add(a,b,c);

   print(c);

时间复杂度计算:

  ●确定基本操作

  ●计算基本操作次数

  ●选择T(n)

  ●lim(F(n)/T(n))=c

  ●0(T(n))为时间复杂度

  上例子的时间复杂度为O(max_s);

--------------------------------------------------------------------------------

二:

链表

  1、知识点

  ●逻辑次序与物理次序不一致存储方法;

  ●单链表的定义:

术语(头结点、头指针等)

  ●注意带头结点的单链表与不带头结点的单链表区别。

(程序员考试一般不考带头结点,因为稍难理解)

  ●插入、删除、遍历(p==NULL表明操作完成)等操作

  ●循环链表:

定义,存储表示,操作;

  ●双向链表:

定义,存储方法,操作;

  单链表和循环链表区别在最后一个指针域值不同。

  2、操作

  ●单链表:

插入X,删除X,查找X,计算结点个数

  ●单链表的逆置(中程曾考)

  head->

NULL/p->

a1/p->

a2/p->

a3/p……an/NULL注:

p代表指针;

NULL/p代表头结点

  =》head->

an/p->

an-1/p->

an-2/p……a1/NULL

  ●循环链表的操作:

插入X,删除X,查找X,计算结点个数;

    用p=head->

next来判断一次计算结点个数完成;

  程序段如下:

  k=0;

  do{

   k++;

   p=p->

next;

  }while(p!

=head->

next);

  ●双向链表

  ●多项式相加

  ●有序链表合并

已知两个字符串S,T,求S和T的最长公子串;

  1、逻辑结构:

字符串

  2、存储结构:

数组

  3、算法:

 精化(精细化工)**老顽童注:

此处“精细化工”说明好像不对!

  s="

abaabcacb"

  t="

abdcabcaabcda"

  当循环到s.len-1时,有两种情况:

s="

、s="

      s.len-2时,有三种情况:

       .

      1s.len种情况

程序思路:

  tag=0//没有找到

  for(l=s.len;

l>

0&

&

!

tag;

l--){

   判断长度为l的s中的子串是否为t的子串;

   若是:

tag=1;

  长度为l的s的子串在s中有(s.len-l+1)个。

  子串0:

 0~l-1

    1:

    1~l      

    2:

    2~l+1      

    3:

    3~l+2

     ……

     ……

    s.len-l:

 s.len-l~s.len-1

  由上面可得:

第j个子串为j~l+j-1。

  判断长度为l的s中的子串是否为t的子串:

  for(j=0;

j<

S.LEN-L+1&

TAG;

J++){

   判断s中长度为l的第j个子串是否为t的子串;

   如果是:

  模式结构:

  tag=0;

tag==0;

   for(j=0;

J++){

    ?

?

用模式匹配方法确定s[j]~s[l+j-1]这个字符串是否为t的子串;

//好好想想

   若是,tag=1;

  在前面笔者编了一些程序:

链表,长整型数相加,三元组表转置以及一些简单的函数.其实有些算法想想是很简单,不过写起来还是需要一定耐心和C基础的,如果你自己觉得各算法都很懂了,不妨开机编编试试.或许会有一些新的发现与体会.

栈和队列

  1、知识点:

  ●栈的定义:

操作受限的线性表

  ●特点:

后进先出

  ●栈的存储结构:

顺序,链接

   /push(s,d)

  ●栈的基本操作:

   pop(s)

  栈定义:

  struct{

   datatypedata[max_num];

   inttop;

  };

  ●队列定义

  特点:

先进先出

  /入队列in_queue(Q,x)

  ●队列的操作:

  出队列del_queue(Q)

  ●队列存储结构:

  链队列:

  Typedefstructnode{

   Datatypedata;

   Structnode*next;

  }NODE;

  Typedefstruct{

   NODE*front;

   NODE*rear;

  }Queue;

  顺序队列:

   intfront,rear;

  问题:

  队列ó

线性表

  假溢出<

=循環队列

  队列满,队列空条件一样<

=浪费一个存储空间

  递归

  定义:

问题规模为N的解依赖于小规模问题的解。

问题的求解通过小规模问题的解得到。

  包括二个步骤:

1)递推6!

5!

4!

3!

2!

1!

0!

  2)回归720<

=120<

=24<

=6<

=2<

=1<

=0

  递归工作栈实现递归的机制。

  2、有关算法:

  1)顺序,链表结构下的出栈,入栈

  2)循環,队列的入队列,出队列。

  3)链队列的入队列,出队列。

  4)表达式计算:

后缀表达式35+6/4368/+*-

          中缀表达式(3+5)/6-4*(3+6/8)

  由于中缀比较难处理,计算机内一般先将中缀转换为后缀。

  运算:

碰到操作数,不运算,碰到操符,运算其前两个操作数。

   中缀=>

后缀

  5)迷宫问题

  6)线性链表的递归算法一个链表=一个结点+一个链表

  intfuction(NODE*p){

   if(p==NULL)return0;

   elsereturn(function(p->

next));

  树与二叉树

  一、知识点:

  1.树的定义:

data_struct(D,R);

  其中:

D中有一个根,把D和出度去掉,可以分成M个部分.

  D1,D2,D3,D4,D5…DM

  R1,R2,R3,R4,R5…RM

  而子树Ri形成树.

  1)递归定义高度

  2)结点个数=1

   

--0

--1

O--2

此树的高度为2

  2.二叉树定义:

  结点个数>

=0.

  3.术语:

左右孩子,双亲,子树,度,高度等概念.

  4.二叉树的性质

  ●层次为I的二叉树I层结点2I个

  ●高度为H的二叉树结点2H+1-1个

  ●H(点)=E(边)+1

  ●个数为N的完全二叉树高度为|_LOG2n_|

  ●完全二叉树结点编号:

从上到下,从左到右.

i结点的双亲:

|_i/2_||_i-1/2_| 

i结点的左孩子:

2i2i+1 

i结点的右孩子:

2i+12i+24 

7

(根)1为起点0为起点 

  二叉树的存储结构:

    1)扩展成为完全二叉树,以一维数组存储。

F

数组下标0123456789101112

元素ABCDEFGH    I

    2)双亲表示法 

数组下标012345678

元素ABCDEFGHI

双亲-100122334

    3)双亲孩子表示法

数组下标012345…

元素ABCDEF…

双亲-100122…

左子134   …

右子2-15   …

结构:

    typedef 

     datatype 

data;

     int 

parent;

lchild;

rchild;

    }NODE;

    NODE 

tree[N];

// 

生成N个结点的树

    4) 

二叉链表

    5) 

三叉链表

    6) 

哈夫曼树

  5.二叉树的遍历

   先根 

   中根 

栈 

中根遍历(左子树)根(右子树),再用相同的方法处理左子树,右子树.

   后根 

/

   先,中序已知求树:

先序找根,中序找确定左右子树.

   层次遍历(队列实现)

  6.线索二叉树(穿线树)

   中序线索二树树目的:

利用空指针直接得到中序遍历的结果.

   手段(方法):

左指针为空,指向前趋,右指针为空,指向后继.

  结点结构:

ltag 

Lch 

Data 

rch 

rtag 

  Ltag=0,lch指向左孩子,ltag=1,指向前趋结点

  Rtag=0,rch指向右孩子;

rtag=1,指向后继结点

  中序遍历:

1) 

找最左结点(其左指针为空)

    2) 

当该结点的rtag=1,该结点的rch指向的就为后继

    3) 

当rtag=0,后继元素为右子树中最左边那个

  N个结点的二树有空指针N+1个

  排序查找是笔者觉得最头疼的算法了,常搞混去的啊.不知道各位学得如何,如果不错,还请告诉我一些经验!

查找 

一、 

知识点    /静态查找->

数组  

  1、 

什么是查找

          动态查找->

链树

  ●顺序查找,时间复杂度 

O(n)

  ●折半查找:

条件:

有序;

时间复杂度 

O(nlog2n) 

(时间复杂度实际上是查找树的高度)

  ●索引查找:

第I+1块的所有元素都大于第I块的所有元素。

   算法:

根据index来确定X所在的块(i) 

时间复杂度:

m/2    

      在第I块里顺序查找X     

 时间复杂度:

n/2 

   总的时间复杂度:

(m+n)/2

  ●二叉排序树 1)定义:

左子树键值大于根节点键值;

右子树键值小于根的键值,其左右子树均为二叉排序树。

 

         2)特点:

中序遍历有序->

(删除节点用到此性质)

         3)二叉排序树的查找:

如果根大于要查找的树,则前左子树前进,如果根小于要查找的树,则向右子树前进。

         4)结点的插入->

二叉排序树的构造方法

         5)结点删除(难点)  

1、右子树放在左子树的最右边

                    2、左子树放在右子树的最左边

  ●avl树(二叉平衡树):

左右子树高度只能差1层,即|h|<

=1其子树也一样。

  ●B树:

n阶B树满足以下条件 1)每个结点(除根外)包含有N~2N个关链字。

                2)所有叶子节点都在同一层。

                3)B树的所有子树也是一棵B树。

   特点:

降低层次数,减少比较次数。

排序

一、知识点

  1、排序的定义

         /内排序:

只在内存中进行

  2、排序的分类

         外排序:

与内外存进行排序 

   内排序:

   /直接插入排序

    1)插入排序

          shell排序

          /冒泡排序

    2)交换排序 

          快速排序

           /简单选择排序

    3)选择排序 

            

锦标赛排序

    4)归并排序(二路)

    5)基数排序(多关链字排序)

  3、时间复杂度(上午题目常考,不会求也得记住啊兄弟姐妹们!

         * 

15 

*

    /稳定   

*(前后不变) 

  排序  

     

不稳定 * 

*(前后改变)

  经整理得:

选择、希尔、堆、快速排序是不稳定的;

直接插入、冒泡、合并排序是稳定的。

 ●锦标赛排序方法:

 13  16  11  18  21  3  17  6

              /     /    /    /

             13     11     3     6

                   /          /

                 11           3

                           /

                       3(胜出,将其拿出,并令其为正无穷&

GoOn)

  ●归并排序方法:

  13  16  11  18  21  3  17  6

              /     /    /    /

             13,16   11,18   3,21   6,17

              11,13,16,18       3,6,17,21

                           /

                 3,6,11,13,16,17,18,21

  ●shell排序算法:

1)定义一个步长(或者说增量)数组D[m];

其中:

D[m-1]=1(最后一个增量必须为1,否则可能不完全)

         2)共排m趟,其中第i趟增量为D[i],把整个序列分成D[i]个子序列,分别对这D[i]个子序列进行直接插入排序。

        程序如下:

for(i=0;

m;

i++)

              {for(j=0;

d[i];

j++)

               {对第i个子序列进行直接插入排序;

 

                  注意:

下标之差为D[i];

               }

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 英语

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1