p=p->Next;
i++;
}
if(i==K)returnp;
/*找到第K个,返回指针*/
elsereturnNULL;
/*否则返回空*/
}
(2)按值查找:
Find
List*Find(ElementTypeX,List*PtrL)
{
List*p=PtrL;
while(p!
=NULL&&p->Data!
=X)
p=p->Next;
returnp;
}
10、插入(在链表的第i-1(1≤i≤n+1)个结点后插入一个值为X的新结点)
List*Insert(ElementTypeX,inti,List*PtrL)
{List*p,*s;
if(i==1){/*新结点插入在表头*/
s=(List*)malloc(sizeof(List));/*申请、填装结点*/
s->Data=X;
s->Next=PtrL;
returns;/*返回新表头指针*/
}
p=FindKth(i-1,PtrL);/*查找第i-1个结点*/
if(p==NULL){/*第i-1个不存在,不能插入*/
printf("参数i错");
returnNULL;
}else{
s=(List*)malloc(sizeof(List));/*申请、填装结点*/
s->Data=X;
s->Next=p->Next;/*新结点插入在第i-1个结点的后面*/
p->Next=s;
returnPtrL;
}
}
11、删除(删除链表的第i(1≤i≤n)个位置上的结点)
List*Delete(inti,List*PtrL)
{List*p,*s;
if(i==1){/*若要删除的是表的第一个结点*/
s=PtrL;/*s指向第1个结点*/
PtrL=PtrL->Next;/*从链表中删除*/
free(s);/*释放被删除结点*/
returnPtrL;
}
p=FindKth(i-1,PtrL);/*查找第i-1个结点*/
if(p==NULL){
printf(“第%d个结点不存在”,i-1);returnNULL;
}elseif(p->Next==NULL){
printf(“第%d个结点不存在”,i);returnNULL;
}else{
s=p->Next;/*s指向第i个结点*/
p->Next=s->Next;/*从链表中删除*/
free(s);/*释放被删除结点*/
returnPtrL;
}
}
12、链表不具备的特点是1。
①可随机访问任一节点②插入删除不须要移动元素
③不必事先估计存储空间④所需空间与其长度成正比
13、带头结点的单链表head为空的判定条件是2。
①head==NULL②head->next==NULL
③head->next==head④head!
=NULL
14、如果最常用的操作是取第i个结点及其前驱,则采用4存储方式最节省时间。
①单链表②双链表③单循环链表④顺序表
第三章Chapter3栈(stacks)和队列(queues)
1、栈是限定仅能在表尾一端进行插入、删除操作的线性表。
2、栈的特点是“后进栈的元素先出栈”(lastin,firstout),故栈又称为后进先出表(LIFO)。
3、一个栈是一些元素的线形列表,其中元素的插入和删除均在表的同一端进行。
插入和删除发生的一端称为栈顶(thetopofthestack)。
4、第一个进栈的元素在栈底,
最后一个进栈的元素在栈顶,
第一个出栈的元素为栈顶元素,
最后一个出栈的元素为栈底元素。
5、连续栈(ContiguousStack)的类型定义
#defineMaxStack50
Typedefstruct
{datatypestack[MaxStack];
inttop;
}Seqstack;
Seqstack*s;
6、判断栈是否已满?
viodPush(Seqstack*s,datatypex)
{
if(s->top>=MaxStack-1)printf(“overflow”);
else{
s->top++;
s->stack[s->top]=x;}
}
7、判断栈是否为空?
datatypepop(Seqstack*s)
{if(s->top<0)
{printf(“underflow”);return(NULL);}
return(s->stack[s->top]);
s->top--;
}
8、返回栈顶元素的值,栈不发生变化。
datatypetop(Seqstack*s)
{if(s->top<0)
{printf(“underflow”);return(NULL);}
return(s->stack[s->top]);
}
9、链栈(LinkedStack)的类型定义
栈的链式存储结构称为链栈,它是运算受限的单链表,插入和删除操作仅限制在表头位置上进行。
由于只能在链表头部进行操作,故链表没有必要像单链表那样附加头结点。
栈顶指针就是链表的头指针。
链栈的类型说明如下:
typedefstructstacknode{
datatypedata
structstacknode*next
}stacknode
10、链式栈的特点:
链式栈无栈满问题;空间可扩充;插入与删除仅在栈顶处执行;链式栈的栈顶在链头;适合于多栈操作。
11、栈是限定仅能在表的一端进行插入、删除操作的线性表。
12、栈的元素具有后进先出的特点。
13、栈顶元素的位置由栈顶指针的指示,进栈、出栈操作要修改栈顶指针。
14、抽象数据类型队列的定义:
队列(Queue)也是一种运算受限的线性表。
它只允许在表的一端进行插入,而在另一端进行删除。
允许删除的一端称为队头(front),允许插入的一端称为队尾(rear)。
15、队列亦称作先进先出(FirstInFirstOut)的线性表,简称FIFO表。
16、双端队列:
就是限定插入和删除操作在表的两端进行的线性表。
17、链队列结点定义:
typedefstructQnode
{QElemTypedata;
structQNode*next;
}QNode,*QueuPtr;
18、队列的顺序存储结构称为顺序队列,在队列的顺序存储结构中,除了用一组地址连续的储存单元依次存放从队头到队尾的元素之外,尚需要附设两个指针front和rear分别指示队列头元素和队列尾元素的位置。
19、在非空队列中,头指针始终指向队头元素,而尾指针始终指向队尾元素的下一位置。
20、栈的特点是先进后出,队列的特点是先进后出。
21、栈和队列的共同特点是只允许在端点处插入和删除元素。
22、一个栈的进栈序列是a,b,c,d,e,则栈的不可能的输出序列是C。
(A)edcba(B)decba(C)dceab(D)abcde
23、若已知一个栈的进栈序列是p1,p2,p3,…,pn。
其输出序列为1,2,3,…,n,若p3=1,则p1为C。
(A)可能是2(B)一定是2(C)不可能是2(D)不可能是3
24、设有一个空栈,栈顶指针为1000H(十六进制,下同),现有输入序列为1、2、3、4、5,经过PUSH,PUSH,POP,PUSH,POP,PUSH,PUSH后,输出序列是3,栈顶指针是8。
①5、4、3、2、1②2、1③2、3
④3、4⑤1002H⑥1004H
⑦1005H⑧1003H
24、一个队列的入队序列是若1,2,3,4,则队列的输出序列是B。
(A)4,3,2,1(B)1,2,3,4
(C)1,4,3,2(D)3,2,4,1
25、若用一个大小为6的一维数组来实现循环队列,且当前rear和front的值分别为0和3。
当从队列中删除一个元素,再加入两个元素后,rear和front的值分别是B。
(A)1和5(B)2和4(C)4和2(D)5和1
26、有5个元素,其入栈次序为A、B、C、D、E,在各种可能的出栈次序中,以元素C、D最先出栈(即C第一个且D第二个出栈)的次序有哪几个?
C、D、B、A、EC、D、E、B、A
C、D、B、E、A
第六章树和二叉树
1、树型结构是一类重要的非线性结构。
2、树的定义:
树是n(n>=0)个结点的有限集T,T为空时称为空树,否则它满足如下两个条件:
(1)有且仅有一个特定的称为根的结点;
(2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1,T2,T3…Tm,其中每个子集又是一棵树,并称其为根的子树。
3、基本术语
结点——表示树中的元素,包括数据项及若干指向其子树的分支
结点的度(degree)——结点拥有的子树数
叶子(leaf)——度为0的结点
孩子(child)——结点子树的根称为该结点的孩子
双亲(parents)——孩子结点的上层结点叫该结点的~
兄弟(sibling)——同一双亲的孩子
树的度——一棵树中最大的结点度数
结点的层次(level)——从根结点算起,根为第一层,它的孩子为第二层……
深度(depth)——树中结点的最大层次数
森林(forest)——m(m0)棵互不相交的树的集合
例题:
4、二叉树是由n(n>=0)个结点的有限集合构成,此集合或者为空集,或者由一个根结点及两棵互不相交的左右子树组成,并且左右子树都是二叉树。
二叉树可以是空集合,根可以有空的左子树或空的右子树。
性质1:
在二叉树的第i层上至多有2i-1个结点(i>=1)。
性质2:
深度为k的二叉树至多有2k-1个结点(k>=1)。
性质3:
对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1。
性质4:
具有n个结点的完全二叉树的深度为log2n+1。
性质5:
如果对一棵有n个结点的完全二叉树的结点按层序编号(从第1层到第log2n+1层,每层从左到右),则对任一结点i(1<=i<=n),有:
(1)如果i=1,则结点i无双亲,是二叉树的根;如果i>1,则其双亲是结点i/2。
(2)如果2i>n,则结点i为叶子结点,无左孩子;否则,其左孩子是结点2i。
(3)如果2i+1>n,则结点i无右孩子;否则,其右孩子是结点2i+1。
一棵深度为k且有2k-1个结点的二叉树称为满二叉树。
如:
5、二叉树的存储结构
●顺序存储结构
defineMAX-TREE-SIZE100
TypedefTelemTypeSqBiTree[MAX-TREE-SIZE];
SqBitreebt;
缺点是有可能对存储空间造成极大的浪费。
●链式存储结构
二叉链式存储结构
typedefstructBiTNode
{TElemTypedata;
structBiTNode*lchild,*rchild;
}BiTNode,*BiTree;
三叉链表
typedefstructnode
{datatypedata;
structnode*lchild,*rchild,*parent;
}JD;
6、遍历二叉树
二叉树是由三个基本单元组成:
根结点、左子树和右子树。
若限定先左后右,则只有前三种情况,分别称之为先(根)序遍历,中(根)序遍历和后(根)序遍历。
(1)先序遍历算法
若二叉树为空树,则空操作;否则,
●访问根结点;
●先序遍历左子树;
●先序遍历右子树。
voidPreOrder(BiTreebt){/*先序遍历二叉树bt*/
if(bt==NULL)return;/*递归调用的结束条件*/
Visite(bt->data);/*
(1)访问结点的数据域*/
PreOrder(bt->lchild);/*
(2)先序递归遍历bt的左子树*/
PreOrder(bt->rchild);/*(3)先序递归遍历bt的右子树*/}
例题:
先序遍历序列:
ABDC
voidpreorder(JD*bt)
{if(bt!
=NULL)
{printf("%d\t",bt->data);
preorder(bt->lchild);
preorder(bt->rchild);
}
}
(2)中序遍历算法
若二叉树为空树,则空操作;否则,
●先序遍历左子树;
●访问根结点;
●先序遍历右子树。
voidInOrder(BiTreebt){/*先序遍历二叉树bt*/
if(bt==NULL)return;/*递归调用的结束条件*/
InOrder(bt->lchild);/*
(2)先序递归遍历bt的左子树*/
Visite(bt->data);/*
(1)访问结点的数据域*/
InOrder(bt->rchild);/*(3)先序递归遍历bt的右子树*/}
例题:
中序遍历序列:
BDAC
(3)后序遍历算法
若二叉树为空树,则空操作;否则,
●先序遍历左子树;
●先序遍历右子树;
●访问根结点。
voidPostOrder(BiTreebt){/*后序遍历二叉树bt*/
if(bt==NULL)return;/*递归调用的结束条件*/
PostOrder(bt->lchild);/*
(1)后序递归遍历bt的左子树*/
PostOrder(bt->rchild);/*
(2)后序递归遍历bt的右子树
Visite(bt->data);/*(3)访问结点的数据域*/}
例题:
后序遍历序列:
DBCA
(4)层次遍历
所谓二叉树的层次遍历,是指从二叉树的第一层(根结点)开始,从上至下逐层遍历,在同一层中,则按从左到右的顺序对结点逐个访问。
层次遍历序列:
123456
7、例题:
1、
先序序列:
ABCDEFGHK
中序序列:
BDCAEHGKF
后序序列:
DCBHKGFEK
层次序列:
ABECFDGHK
2、
若先序遍历此二叉树,按访问结点的先后次序将结点排列起来,其先序序列为:
-+a*b-cd/ef
按中序遍历,其中序序列为:
a+b*c-d-e/f
按后序遍历,其后序序列为:
abcd-*+ef/-
8、
(1)查询二叉树中某个结点
StatusPreorder(BiTreeT,ElemTypex,BiTree&p){
//若二叉树中存在和x相同的元素,则p指向该结点并
//返回OK,//否则返回FALSE
if(T){
if(T->data==x){p=T;returnOK,}
else{
if(Preorder(T->lchild,x,p))returnOK;
else(Preorder(T->rchild,x,p))returnOK;
}//else
}//if
elsereturnFALSE;
}
(2)计算二叉树中叶子结点的个数
intCountLeaf(BiTreeT){
//返回指针T所指二叉树中所有叶子结点个数
if(!
T)return0;
if(!
T->lchild&&!
T->rchild)return1;
else{
m=CountLeaf(T->lchild);
n=