数据结构笔记.docx

上传人:b****8 文档编号:10658311 上传时间:2023-02-22 格式:DOCX 页数:32 大小:32.54KB
下载 相关 举报
数据结构笔记.docx_第1页
第1页 / 共32页
数据结构笔记.docx_第2页
第2页 / 共32页
数据结构笔记.docx_第3页
第3页 / 共32页
数据结构笔记.docx_第4页
第4页 / 共32页
数据结构笔记.docx_第5页
第5页 / 共32页
点击查看更多>>
下载资源
资源描述

数据结构笔记.docx

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

数据结构笔记.docx

数据结构笔记

2005年北京交通大学计算机专业考研辅导班笔记

(05年有好多内容和04年一样,04年有不同我会特别用蓝色注明)

第一章:

概论(05年)

1.设有两个算法在同一机器上运行,其执行时间分别为100*n**2和2**n,要是前者快于后者,n至少要多大?

求不等式100n**2<2**n,àn>=15

2.算法的时间复杂度仅与问题的规模相关吗?

事实上,时间复杂度不仅与问题的规模有关,还与问题的初始状态相关,如起泡排序里时间复杂度就与排序的初始状态有关。

3.若所需额外空间相对于输入数据量是常数,则称算法为原地工作!

(掌握概念)

有可能出这样的题:

给你个算法让你判断它是否是原地工作。

如:

简单排序,起泡排序等!

总结:

第一章考的内容不多,主要是复杂度问题

概论(04年)

强调的内容和05年差不多,但着重讲了算法复杂度的计算。

如下:

1.

(1)x=0;y=0;1次

(2)for(k=1;k<=n;k++)n+1次

(3)x++;n次

(4)for(k=1;k<=n;k++)n+1次

(5)for(j=1;j<=n;j++)n(n+1)次

(6)y++n**2次

2.x=11次

for(k=1;k<=n;k++)n+1次

for(j=1;j<=i;j++)∑(i+1)(求和下限i=1,上限n+1)

for(k=1;k<==j;k++)

x++;∑∑j(第一个求和下限i=1,上限n;第二个求和下限j=1,上限为i)

=∑(i+1)/2(求和下限i=1,上限n)

=(n(n+1)(2n+1))/12+(n(n+1))/4

3.简单选择排序和起泡排序的比较次数

第二章:

线性表(05年)

1.熟悉线性表的逻辑结构及其性质(书上有)

2.理解插入,删除,定位这三个算法及过程(顺序表,各种链表应熟悉)

3.循环链表的用法(约瑟夫环,猴子选大王(参看04年填程序第二题)自己编一下程序)

4.双向循环链表判空(head->next=head或head->pre=head带头结点),判满的条件

以及它的插入和删除结点的操作。

5.在顺序表中插入或删除一个结点需平均移动多少个结点?

具体的移动次数取决于哪两个因素?

答:

参看书P25

取决于顺序表的长度n,和需要插入和删除的位置i(i越接近n需要移动的结点越少)

5.为什么在单循环链表中设尾指针比设头指针好?

答:

用尾指针可以使得查找链表的开始结点和终端结点都很方便。

设一带头结点的单循环链表,其尾指针为rear则开始结点和终端结点的位置分别rear->next->next和rear.查找时间都是O

(1).若用头结点表示则查找终端结点的时间是O(n);

6.在单链表,双链表和单循环链表中,若只知道指针p指向某结点,不知道头指针,能否将结点*p从中删除?

答:

单链表不行

双链表可以O

(1)

单循环可以O(n)从p开始往后,总可以找到p前面的一个结点。

7.下述算法的功能是什么?

LinklistDemo(linklistL)

{//L是头结点

listNode*q,*p;

if(L&&L->next)//保证有两个结点

{q=L;L=L->next;p=L;

while(p->next)p=p->next;

p->next=q;q->next=Null;

}returnL;

}//该程序是把第一个结点挪到最后,第二个结点变为第一,返回的L为新链表的头指针

答:

若L指向的单链表至少有两个结点,将第一个结点移到终端结点之后成为新的终端结点。

而L指向原来的第二个结点,使其成为新的开始结点,并返回新链表的头指针;否则直接返回L值不作任何变动

(老师强调了在做阅读程序的题目时,一定要把其描写得具体些,这样才能保证多拿分)

8.试分别用顺序表和单链表作为存储结构,写程序对其就地逆置,要求辅助空间为O

(1).

9.顺序表L是递增(或递减)有序表,将x插入后,使其仍然有序。

10.已知L1,L2分别指向两个单链表的头结点,试写一算法将两个链表连接在一起,并分析算法的时间复杂度(min(m,n)短的放前面,把第二个链表的头结点去掉。

从短的头结点开始一直找到尾部,并让尾结点指向长链表(last->next=L2->next))

11.设A,B两个单链表,其表中元素递增有序。

试写一算法将A,B归并成一个递减的C,要求辅助空间为O

(1),并求时间复杂度(参看P21)

12.约瑟夫环应用

以上题目希望大家能自己动手做做

第三章栈和队列(05年)

1.栈和队列:

受限的线性表。

一般的线性表有:

插入点n+1个,删除点n个

栈,队列:

插入点1个,删除点1个

2.入栈,出栈,入队,删除队头的操作均应掌握(包括算法)

3.掌握循环队列

4.例题P48数制转换

5.括号匹配知道是怎么回事就行

6.迷宫求解录音里有老师详细讲解

7.回文游戏顺读与逆读字符串一样(不含空格)

(1)读入字符串

(2)去空格(3)压入栈(4)依次出栈与原字符串比较

若不等则非回文,若直到栈空都相等则为回文。

考虑另一种方法:

若字符串的长度为奇数,则不需比较为非回文。

否则可先读入一半字符入栈,然后依次出栈和剩下的字符比较!

自己可用这种方法编写一下。

8.地图四染色问题(未考过)

使地图中相邻的不重色,最少用4种颜色可以实现。

利用栈回溯。

设一个邻接矩阵R[][],主对角线上的元素均为零。

其于元素如R1,3,如果第一个区域和第三个区域相邻的话则R1,3为1,否则为0。

再使用一个工作数组S[]用来存放已填色区域的号码。

Voidmapcolor(intR[][],intn,intS[])//n表示地图共有n个区

{S[1]=1;//1号区填1号色

a=2;j=1;//a为区号,j为色号

while(a<=n)//a>n表示填色完成

{while((j<=4)&&(a<=n))

{k=1;//k表示已填色的区域

while((k

=j))k=k+1;

//若不邻,或相邻且不重色,对下一个区进行判断

if(k

else{s[a]=j;a=a+1;j=1;}//相邻不重色,又从1号区着色

}

if(j>4){a=a-1;j=s[a]+1;}//对当前需着色区域a来说,1-4种颜色都不行,则说明上一个错了,对上一个进行重填

}

9.四皇后问题

#include

#definen4//n是皇后的个数

intm=0,a[n];//a[i]存放第i个皇后放置的行号

intok(inti,intj)//检查(i,j)能否放棋子

{intj1,i1,ok1;

j1=j;i1=i;ok1=1;

while((j1>1)&&ok1){j1--;ok1=a[j1]!

i;}//查左边那列该行是否有皇后

j1=j;i1=i;//检查对角线上能否放

while((j1>1)&&(i1>1)&&ok1){j1--;i1--;ok1=a[j1]!

i1;}

j1=j;i1=i;//检查另一对角线能否放

while((j1>1)&&(i1

i1;}

returnok1;

}

voidqueen(intj)//从第j列开始试探

{inti;

if(j>n)//放完了,打印摆法计数

{m++;printf(“m=%d“,m);

for(i=1;i<=n;i++)printf(“%d”,a[i]);

printf(“\n”);

}

elsefor(i=1;i<=n;i++)

if(ok(i,j))//检查(i,j)上能否放

{a[j]=i;queen(j+1);}//在(i,j)上放,第j列的皇后在第i行

}

main()

{queen

(1);}//从第一列开始试探

10.队列:

注意循环队列判空判满的条件(增加一个元素的空间)

11.在非循环队列中:

当Q.front=Q.rear<>0时能否判空?

当Q.rear=0时,能否判空?

Q.front=0时,能否判空不能

13.循环队列判空判满及求长度

空:

Q.front=Q.rear

满:

(Q.rear+1)%MAXSIZE=Q.front

长度:

(Q.rear-Qfront+MAXSIZE)%MAXSIZE

14.k阶斐波那挈序列

试用循环队列编写求k阶斐波那挈序列中的前n+1项(f0.,f1,f2,….fn)的算法,要求满足fn<=max而fn+1>max,其中max为某个约定的常数。

(注意本题所用的循环队列的容量为k)

方法一:

fi=fi-1+…fi-k(未考过)

而fk=f0+….f(k-1),用fk冲掉f0,用f(k+1)冲掉f1,依次循环求出fk,直到发fk>max为止

Voidfb(intk;intmax)

{for(i=0;i<=k-2;i++){f[i]=0;cq.elem[i]=0;}

cq.elem[k-1]=1;cq.rear]k-1;n=k;

while(cq.elem[cq.rear]

{f[n]=0;

for(j=0;j

cq.rear=(cq.rear+1)%k;

cq.elem[cq.rear]=f[n];n++;

}

if(cq.elem[cq.rear]>max)n=n-2;

elsen=n-1;

if(max=1){n=k;f[k]=1;}

}

方法二:

fi=f(i-1)+…f(i-k);f(i+1)=fi+f(i-1)+….f(i-k+1)

两式相减:

f(i+1)=2*fi-f(i-k)

f(k)=2*f(k)-f(0)(时间复杂度要小)

Voidfb(intk;intmax;)

{for(i=0;i<=k-2;i++){f[i]=0;cq.elem[i]=0;}

cq.elem[k-1]=cq.elem[k]=1;cq.rear=k;n=k+1;f[k-1]=f[k]=1;

while(cq.elem[cq.rear]

{j=(cq.elem+1)%(k+1);

f[n]=cq.elem[cq.rear]*2-cq.elem[j];

cq.elem[j]=f[n];cq.rear=j;n++;

}

if(cq.elem[cq.rear]>max)n=n-2;elsen=n-1;

if(max==1){n=k;f[k]=1;}

if(max==0)n=k_2;

}

第四章:

1.重点:

KMP算法

(要求书上的程序要看懂,比如说04年就出了模式匹配的阅读程序的题目)

会求next和nextval数组的值。

本章考试内容基本就是几个形式,要么给你个字符串要求它的next或nextval数组,或者会给出你主串和子串,要求你写出匹配的过程,还有就是04年的那种阅读的形式了!

第五章:

数组,广义表

1.两类矩阵

1):

特殊矩阵:

非0元的分布有一定规则。

如对称矩阵,三角矩阵,对角矩阵

2):

稀疏矩阵

2.对称矩阵(出选择和填空的机会较大)

对称矩阵最少需要多少个存储单元n(n+1)/2个

关系:

k=(参看P95)

注意在确定对称矩阵和对应一维数组的位置的题目时一定要注意是以行序还是列序,下标是从0开始还是从1开始

例:

若1<=i,j<=n已知i,j求k公式1

k=(i*(i-1))/2+j-1(i>=j)

k=(j*(j-1))/2+i-1(i

若0<=i,j<=n-1已知i,j求k公式2

k=(i*(i+1))/2+j(i>=j)

k=(j*(j+1))/2+i(i

若1<=i,j<=n,已知k,求i,j(用公式1)

已知k=49求i,j

将j=i代入(公式1)得k+1<=i(i+1)/2求使之成立的最小i.然后再将i值代入(公式1)求出j

若0<=i,j<=n-1已知k求i,j(同上用公式2)

以上方法希望大家掌握!

3.下三角矩阵(类似于对称矩阵)

4.上三角矩阵

若0<=i,j<=n-1已知i,j求k(要求自己会推导)

第p行上恰好有n-p个元素,在i行上ai,j前有j-i个元素,i前有i个完整行

所以第I行前共有元素个数为:

∑(n-p)(求和下限为p=0,上限为i-1)=

(i*(2n-i+1))/2

所以k=(i*(2n-i+1))/2+j-ii<=j(上三角)

若1<=i,j<=n已知i,j求k的情况大家可以自己去推导

k=((i-1)(2n-i+2))/2+(j-i+1)-1

注意:

以上的k值均从0开始。

其实我认为做这种题目,首先看两点,一是矩阵的起始下标,二是数组的开始下标!

检验你的公式是否正确你可以取一个比较容易计算的元素比如a0,2代入到公式检验下,因为a0,2是矩阵的第三个元素!

三角矩阵的存储单元要比对称矩阵多一个元素,用于存储相对三角矩阵的常数值c,存放在第n(n+1)/2+1个单元里

例如:

已知一个9阶上三角矩阵A按行存储在一维数组B中,B[0]存放矩阵中第一个元素a11则B[31]存放元素(a5,6),按列序存放,存放元素(a4,8)

上面题目在录音中均有详细讲解过程。

以上计算每年至少会有一个填空题!

5.三对角矩阵

按行序1<=i,j<=n。

Loc(aij)=Loc(a11)+3*(i-1)-1+j-i+2

若一个s(素数)对角矩阵满足下述条件:

若0<=i,j<=n-1,已知i,j求k。

 k=(3*i-1)+(j-i+2)-1=2i+j

若0<=i,j<=n-1已知k求i,ji=(k+1)/3,j=k-2*i.

若1<=i,j<=n 已知i,j求k。

k=3*(i-1)-1+(j-i+2)-1=2*i+j-3

若0<=i,j<=n-1已知k求i,j.i=(k+1)/3+1,j=k-2*i+3

以上公式我认为没有必要去记,可以参考一下人邮出版社的〈数据结构课程辅导与习题解析〉这本书,里面有具体的推导过程。

象上面的所有的计算都有具体例题

   6.随机稀疏矩阵存储(只掌握三元组,行逻辑,十字链表不要求掌握)

    熟悉带行表的稀疏矩阵的存储结构,会根据行表推导原矩阵(参看04年的简答题)

6.广义表:

判断广义表的深度,广度,和表长。

会画广义表用书上的第一种存储结构。

有很多朋友画广义表的时候经常会出错,我觉得可以用一个方法去检验你画的图是否正确!

你可以根据广义表的表达式用gethead()和gettail()函数取得某一个元素(这是一系列的操作组合,参看04年的填空第六题的形式),然后看在你画的广义表中从表头开始取得该元素是否也经历了这些操作就行了

第六章:

树与二叉树

1.掌握二叉树的5个性质,并能灵活运用!

第三个性质的证明必须掌握(参看04年的简答题1)

2.已知一棵度为m的树,有n1个度为1的结点,有n2个度为2的结点,有nm个度为m的结点,问有多少叶子结点?

免费考研网

n0+n1+….+Nm=∑i*ni+1(求和的下限是i=1,上限是m)

n0=∑(i-1)*ni+1

3.两类特殊的二叉树:

 满二叉树(结点数为2**k-1个),完全二叉树(结点号与满二叉树必须对应)

4.性质4的证明 (书上有证明)

5.二叉树的存储结构(书上的定义一定要记住)

顺序存储结构    链式存储

二叉:

  空域   n+1

三叉:

空域n+2

一般有:

在一棵有n个结点,度为k的树中必有n*(k-1)+1个空链域

6.各种遍历的递归和非递归算法均应熟练掌握

中序非递归见P130

先序非递归参看相关的资料

后序非递归:

Voidpostorder_fei(BinNode*t)

{ BinNode*p;

     printf(“post_order_fei:

“');

     top=0;stack[top]=t;

     while(top!

=-1)

     {while(stack[top])

   {top=top+1;

   stack[top]=stack[top-1]->lch;

   top=top-1;

if(top!

=-1)

     {p=stack[top];

      if((!

p->rch)||(p->rch->visited==1))

     {stack[top]=null;

     printf(“%c”,p->data);p->visited=1;

     }

      else

       {top=top+1;stack[top]=p->rch;}

     }

}

}

     }

7.遍历算法的应用举例

(1)求二叉树中叶子结点的个数。

(先序(中序,后序)遍历二叉树,设一个全局变量作为计数器,左右指针为空的结点为叶结点)

intcountleaf(BinTreeT)

{intn1,n2;

if(!

T)return0;

else{if((!

T->lchild)&&(!

T->rchild))

return1;

else{n1=countleaf(T->lchild);//n1存放左子树的叶结点数

n2=countleaf(T->rchild);//n2存放右子树的叶结点数

return(n1+n2);

}

}

}

(2)求二叉树深度(后序遍历 )

基本思想:

二叉树的深度为左右子树的最大深度加1

intDepth(BinTreeT)

{intdep,dep1,dep2;

if(!

T)dep=0;

else{dep1=Depth(T->lch);

dep2=Depth(T->rch);

dep=1+(dep1>dep2?

dep1:

dep2);

}

returndep;

}

(3)复制二叉树(先序遍历)

Voidcopytree(BinTreeroot,BinTree*newroot)//newroot为指向指针的指针

 {if(!

root)*newroot=Null;

else

{*newroot=(BinNode*)malloc(sizeof(BinNOde));

(*newroot)->data=root->data;

copytreer(root->lchild,&((*newroot)->lchild));//复制到左子树

copytree(root->rchild,&((*newroot)->rchild));//复制到右子树

 }

(4)交换二叉树的左右子树(类似先序遍历,用后序也可以,但中序不行)

Voidexchange(BinNode*T)

{BinNode*q;

if(T)

{q=T->lchild;

T->lchild=T->rchild;

T->rchild=q;

exchange(T->lchild);

exchange(T->rchild);

}

}

     (5)建立二叉树的存储结构(不同的定义方法相应有不同的存储结构,现以字符串的形式 根 左子树  右子树定义一棵二叉树(即二叉树的扩展序列)

      如:

              

  以字符串AB*C**D**(*号表示空字符)

statusCreatBitree(BiTree&T)//按先序扩展序列建立二叉树的递归算法

 { scanf(&ch);

if(ch==’‘)T=Null;

else{if(!

(T=(BinNode*)malloc(sizeof(BinNode))));

exit(overflow);

T->data=ch;

CreatBitree(T->lchild);

CreatBitree(T->rchild);

}

returnok;

}

7.已知按某规律遍历二叉树的非扩展序列(也即由先序,中序,后序遍历而得的序列),是否可以唯一确定该二叉树的结构?

结论:

按某规律遍历二叉树的非扩展序列不能唯一确定该二叉树的结构

8.已知按某规律遍历二叉树的扩展序列,能否唯一确定该二叉树的结构?

结论:

先序扩展序列能唯一确定   中序扩展序列不能唯一确定

后序扩展序列能唯一确定(从后往前推导)

     //按后序遍历扩展序列建立二叉树结构的递归算法

     Voidcrt_bt_post(Bitreeptr*bt)

{if(i>=s.len)//I是全局变量,初始值为0,s存放后序扩展序列字符和长度

{bt=stack[top];top=top-1;}//入栈

else

{i++;c=s.ch[i]; 

  if(c=’‘)*bt=Null;

else{*bt=(BiNode*)malloc(sizeof(BiNode));

(*bt)->data=c;

(*bt)->rch=stack[top];top=top-1;

(*bt)->lch=stack[top];top=top-1;

}

top=top+1;stack[top]=*bt;

crt_bt_post(&bt);

}

}

9.层次遍历某二叉树的扩展序列可以唯一确定二叉树的存储结构

按层次遍历的扩展序列建立二叉树非递归算法(pascal)

getnode(varbt:

bitreptr)

begin

i=i+1;e=s.ch[i];

if(c=’‘)thenbt=nil;

elsebegin

new(bt);bt->data=c;que.rear=que.rear+1;que.elem[que.rear]=bt;

end

end

proceedecrt_bt_level(varbt:

bitreptr)

varp:

bitreptr;

begin

que.front=0;que.rear=0;getnode(bt);

whileque.rear<>que.frontdo

begin

que.front=que.front+1;

p=que.elem[que.front];

getnode(p

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

当前位置:首页 > PPT模板 > 简洁抽象

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

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