数据结构算法背诵版.docx
《数据结构算法背诵版.docx》由会员分享,可在线阅读,更多相关《数据结构算法背诵版.docx(25页珍藏版)》请在冰豆网上搜索。
数据结构算法背诵版
数据结构算法背诵
一、线性表
1.逆转顺序表中的所有元素
算法思想:
第一个元素和最后一个元素对调,第二个元素和倒数第二个元素对调,……,依此类推。
voidReverse(intA[],intn)
{
inti,t;
for(i=0;i{t=A[i];A[i]=A[n-i-1];A[n-i-1]=t;}}2.删除线性链表中数据域为item的所有结点算法思想:先从链表的第2个结点开始,从前往后依次判断链表中的所有结点是否满足条件,若某个结点的数据域为item,则删除该结点。最后再回过头来判断链表中的第1个结点是否满足条件,若满足则将其删除。voidPurgeItem(LinkList&list){LinkListp,q=list;p=list->next;while(p!=NULL){if(p->data==item){q->next=p->next;free(p);p=q->next;}else{q=p;p=p->next;}}if(list->data==item){q=list;list=list->next;free(q);}}3.逆转线性链表voidReverse(LinkList&list){LinkListp,q,r;p=list;q=NULL;while(p!=NULL){r=q;q=p;p=p->next;q->next=r;}list=q;}4.复制线性链表(递归)LinkListCopy(LinkListlista){LinkListlistb;if(lista==NULL)returnNULL;else{listb=(LinkList)malloc(sizeof(LNode));listb->data=lista->data;listb->next=Copy(lista->next);returnlistb;}}5.将两个按值有序排列的非空线性链表合并为一个按值有序的线性链表LinkListMergeList(LinkListlista,LinkListlistb){LinkListlistc,p=lista,q=listb,r;//listc指向lista和listb所指结点中较小者if(lista->data<=listb->data){listc=lista;r=lista;p=lista->next;}else{listc=listb;r=listb;q=listb->next;}while(p!=NULL&&q!=NULL){if(p->data<=q->data){r->next=p;r=p;p=p->next;}else{r->next=q;r=q;q=q->next;}}//将剩余结点(即未参加比较的且已按升序排列的结点)链接到整个链表后面r->next=(p!=NULL)?p:q;returnlistc;}二、树1.二叉树的先序遍历(非递归算法)算法思想:若p所指结点不为空,则访问该结点,然后将该结点的地址入栈,然后再将p指向其左孩子结点;若p所指向的结点为空,则从堆栈中退出栈顶元素(某个结点的地址),将p指向其右孩子结点。重复上述过程,直到p=NULL且堆栈为空,遍历结束。#defineMAX_STACK50voidPreOrderTraverse(BTreeT){BTreeSTACK[MAX_STACK],p=T;inttop=-1;while(p!=NULL||top!=-1){while(p!=NULL){VISIT(p);STACK[++top]=p;p=p->lchild;}p=STACK[top--];p=p->rchild;}}2.二叉树的中序遍历(非递归算法)算法思想:若p所指结点不为空,则将该结点的地址p入栈,然后再将p指向其左孩子结点;若p所指向的结点为空,则从堆栈中退出栈顶元素(某个结点的地址)送p,并访问该结点,然后再将p指向该结点的右孩子结点。重复上述过程,直到p=NULL且堆栈为空,遍历结束。#defineMAX_STACK50voidInOrderTraverse(BTreeT){BTreeSTACK[MAX_STACK],p=T;inttop=-1;while(p!=NULL||top!=-1);{while(p!=NULL){STACK[++top]=p;p=p->lchild;}p=STACK[top--];VISIT(p);p=p->rchild;}}3.二叉树的后序遍历(非递归算法)算法思想:当p指向某一结点时,不能马上对它进行访问,而要先访问它的左子树,因而要将此结点的地址入栈;当其左子树访问完毕后,再次搜索到该结点时(该结点地址通过退栈得到),还不能对它进行访问,还需要先访问它的右子树,所以,再一次将该结点的地址入栈。只有当该结点的右子树访问完毕后回到该结点时,才能访问该结点。为了标明某结点是否可以访问,引入一个标志变量flag,当flag=0时表示该结点暂不访问,flag=1时表示该结点可以访问。flag的值随同该结点的地址一起入栈和出栈。因此,算法中设置了两个堆栈,其中STACK1存放结点的地址,STACK2存放标志变量flag,两个堆栈使用同一栈顶指针top,且top的初始值为.1。#defineMAX_STACK50voidPostOrderTraverse(BTreeT){BTreeSTACK1[MAX_STACK],p=T;intSTACK2[MAX_STACK],flag,top=-1;while(p!=NULL||top!=-1){while(p!=NULL){STACK1[++top]=p;STACK2[top]=0;p=p->lchild;}p=STACK1[top];flag=STACK2[top--];if(flag==0){STACK1[++top]=p;STACK2[top]=1;p=p->rchild;}else{VISIT(p);p=NULL;}}}4.二叉树的按层次遍历算法思想:设置一个队列,首先将根结点(的地址)入队列,然后依次从队列中退出一个元素,每退出一个元素,先访问该元素所指的结点,然后依次将该结点的左孩子结点(若存在的话)和右孩子结点(若存在的话)入队列。如此重复下去,直到队列为空。#defineMAX_QUEUE50voidLayeredOrderTraverse(BTreeT){BTreeQUEUE[MAX_QUEUE],p;intfront,rear;if(T!=NULL){QUEUE[0]=T;front=-1;rear=0;while(front{p=QUEUE[++front];VISIT(P);if(p->lchild!=NULL)QUEUE[++rear]=p->lchild;if(p->rchild!=NULL)QUEUE[++rear]=p->rchild;}}}5.建立二叉树(从键盘输入数据,先序遍历递归算法)BTreeCreateBT(){charch;BTreeT;sacnf("%c",&ch);if(ch=='')returnNULL;else{T=(BTree)malloc(sizeof(BTNode));T->data=ch;T->lchild=CreateBT();T->rchild=CreateBT();returnT;}}6.建立二叉树(从数组获取数据)BTreeCreateBT(intA[],inti,intn){BTreep;if(i>n)returnNULL;else{p=(BTree)malloc(sizeof(BTNode));p->data=A[i];p->lchild=CreateBT(A,2*i,n);p->rchild=CreateBT(A,2*i+1,n);returnp;}}T=CreateBT(A,1,n);BTreeCreateBT(intA[],intn){inti;BTree*pT;//对应n个结点申请可容纳n个指针变量的内存空间pT=(BTree*)malloc(sizeof(BTree)*n);//若数组中的某个元素不等于零,则申请相应的结点空间并进行赋值for(i=1;i<=n;i++){if(A[i]!=0){pT[i]=(BTree)malloc(sizeof(BTNode));pT[i]->data=A[i];}else{pT[i]=NULL;}}//修改结点的指针域的内容,使父结点指向左、右孩子结点for(i=1;i<=n;i++){if(pT[i]!=NULL){pT[i]->lchild=pT[2*i];pT[i]->rchild=pT[2*i+1];}}}7.求二叉树的深度(递归算法)intDepth(BTreeT){intldepth,rdepth;if(T==NULL)return0;else{ldepth=Depth(T->lchild);rdepth=Depth(T->rchild);if(ldepth>rdepth)returnldepth+1;elsereturnrdepth+1;}}8.求二叉树的深度(非递归算法)算法思想:对二叉树进行遍历,遍历过程中依次记录各个结点所处的层次数以及当前已经访问过的结点所处的最大层次数。每当访问到某个叶子结点时,将该叶子结点所处的层次数与最大层次数进行比较,若前者大于后者,则修改最大层次数为该叶子结点的层次数,否则不作修改。遍历结束时,所记录的最大层次数即为该二叉树的深度。本算法使用的是非递归的中序遍历算法(其它遍历顺序也可以)。#defineMAX_STACK50intDepth(BTreeT){BTreeSTACK1[MAX_STACK],p=T;intSTACK2[MAX_STACK];intcurdepth,maxdepth=0,top=-1;if(T!=NULL){curdepth=1;while(p!=NULL||top!=-){while(p!=NULL){STACK1[++top]=p;STACK2[top]=curdepth;p=p->lchild;curdepth++;}p=STACK1[top];curdepth=STACK2[top--];if(p->lchild==NULL&&p->rchild==NULL)if(curdepth>maxdepth)maxdepth=curdepth;p=p->rchild;curdepth++;}}returnmaxdepth;}9.求结点所在层次算法思想:采用后序遍历的非递归算法对二叉树进行遍历,遍历过程中对每一个结点判断其是否为满足条件的结点,若是满足条件的结点,则此时堆栈中保存的元素个数再加1即为该结点所在的层次。#defineMAX_STACK50intLayerNode(BTreeT,intitem){BTreeSTACK1[MAX_STACK],p=T;intSTACK2[MAX_STACK],flag,top=-1;while(p!=NULL||top!=-1){while(p!=NULL){STACK1[++top]=p;STACK2[top]=0;p=p->lchild;}p=STACK1[top];flag=STACK2[top--];if(flag==0){STACK1[++top]=p;STACK2[top]=1;p=p->rchild;}else{if(p->data==item)returntop+2;p=NULL;}}}10.交换二叉树中所有结点的左右子树的位置算法思想:按层次遍历二叉树,遍历过程中每当访问一个结点时,就将该结点的左右子树的位置对调。#defineMAX_QUEUE50voidExchangeBT(BTreeT){BTreeQUEUE[MAX_QUEUE],temp,p=T;intfront,rear;if(T!=NULL){QUEUE[0]=T;front=-1;rear=0;while(front{p=QUEUE[++front];temp=p->lchild;p->lchild=p->rchild;p->rchild=temp;if(p->lchild!=NULL)QUEUE[++rear]=p->lchild;if(p->rchild!=NULL)QUEUE[++rear]=p->rchild;}}}11.删除二叉树中以某个结点为根结点的子树算法思想:先序遍历找到符合条件的结点(其它遍历方法亦可),然后删除以该结点为根结点的子树。最后把该结点的父结点的相应的指针域置为NULL。为此,需在算法中设置一个指针变量用以指示当前结点的父结点。#defineMAX_STACK50BTreeDeleteSubtree(BTree&T,intitem){BTreeSTACK[MAX_STACK],q,p=T;inttop=-1;if(T->data==item){DestroyBT(T);T=NULL;returnNULL;}else{while(p!=NULL||top!=-1){while(p!=NULL){if(p->data==item){if(q->lchild==p)q->lchild=NULL;elseq->rchild=NULL;DestroyBT(p);returnT;}STACK[++top]=p;q=p;p=p->lchild;}q=STACK[top--];p=q->rchild;}}}三、查找1.顺序查找的递归算法intRecurSeqSearch(intA[],intn,intkey,inti){if(i>=n)return-1;if(A[i]==key)returni;elsereturnRecurSeqSearch(A,n,key,i+1);}pos=RecurSeqSearch(A,n,key,0);2.折半查找intBinSearch(intA[],intn,intkey){intlow=0,high=n-1,mid;while(low<=high){mid=(low+high)/2;if(key==A[mid])returnmid;if(key>A[mid])low=mid+1;elsehigh=mid–1;}return-1;}3.折半查找的递归算法intRecurBinSearch(intA[],intlow,inthigh,intkey){intmid;if(low>high)return-1;else{mid=(low+high)/2;if(key==A[mid])returnmid;if(key>A[mid])returnRecurBinSearch(A,mid+1,high,key);elsereturnRecurBinSearch(A,low,mid-1,key);}}pos=RecurBinSearch(A,0,n-1,key);4.在按值递增排列且长度为n的线性表中折半查找并插入一元素voidBinInsert(intA[],int&n,intkey){intj,low=0,high=n-1,mid;while(low<=high){mid=(low+high)/2;if(key>A[mid])low=mid+1;elsehigh=mid–1;}for(j=n;j>low;j--)A[j]=A[j-1];A[low]=key;n++;}5.在按值递增排列且长度为n的线性表中折半查找值不小于key的最小元素voidBinSearch(intA[],intn,intkey){intlow=0,high=n-1,mid;while(low<=high){mid=(low+high)/2;if(key==A[mid])returnmid;if(key>A[mid])low=mid+1;elsehigh=mid–1;}if(low<=n-1)returnlow;elsereturn-1;}四、排序1.插入排序算法思想:第i趟插入排序为:在含有i.1个元素的有序子序列中插入一个元素,使之成为含有i个元素的有序子序列。在查找插入位置的过程中,可以同时后移元素。整个过程为进行n.1趟插入,即先将整个序列的第1个元素看成是有序的,然后从第2个元素起逐个进行插入,直到整个序列有序为止。voidInsertSort(intA[],intn){inti,j,temp;for(i=1;i<=n-1;i++){if(A[i]{j=i-1;temp=A[i];while(j>=0&&temp{A[j+1]=A[j];j--;}A[j+1]=temp;}}}2.折半插入排序算法思想:算法同直接插入排序,只不过使用折半查找的方法来寻找插入位置。voidBinInsertSort(intA[],intn){inti,j,low,high,mid,temp;for(i=1;i<=n-1;i++){temp=A[i];low=0;high=i–1;while(low<=high){mid=(low+high)/2;if(temp>A[mid])low=mid+1;elsehigh=mid–1;}for(j=i;j>low;j--)A[j]=A[j-1];A[low]=temp;}}3.冒泡排序算法思想:首先将第1个元素和第2个元素进行比较,若前者大于后者,则两者交换位置,然后比较第2个元素和第3个元素。依此类推,直到第n.1个元素和第n个元素进行过比较或交换为止。上述过程称为一趟冒泡排序,其结果是使得n个元素中值最大的那个元素被安排在最后一个元素的位置上。然后进行第二趟排序,即对前n.1个元素进行同样的操作,使得前n.1个元素中值最大的那个元素被安排在第n.1个位置上。一般地,第i趟冒泡排序是从前n.i+1个元素中的第1个元素开始,两两比较,若前者大于后者,则交换,结果使得前n.i+1个元素中最大的元素被安排在第n.i+1个位置上。显然,判断冒泡排序结束的条件是“在一趟排序中没有进行过交换元素的操作”,为此,设立一个标志变量flag,flag=1表示有过交换元素的操作,flag=0表示没有过交换元素的操作,在每一趟排序开始前,将flag置为0,在排序过程中,只要有交换元素的操作,就及时将flag置为1。因为至少要执行一趟排序操作,故第一趟排序时,flag=1。voidBubbleSort(intA[],intn){inti,j,
t=A[i];
A[i]=A[n-i-1];
A[n-i-1]=t;
}
2.删除线性链表中数据域为
item的所有结点
先从链表的第
2个结点开始,从前往后依次判断链表中的所有结点是否满足条件,若某个
结点的数据域为
item,则删除该结点。
最后再回过头来判断链表中的第
1个结点是否满足条件,若
满足则将其删除。
voidPurgeItem(LinkList&list)
LinkListp,q=list;
p=list->next;
while(p!
=NULL)
if(p->data==item){
q->next=p->next;
free(p);
p=q->next;
}else{
q=p;
p=p->next;
if(list->data==item)
q=list;
list=list->next;
free(q);
3.逆转线性链表
voidReverse(LinkList&list)
LinkListp,q,r;
p=list;
q=NULL;
r=q;
q->next=r;
list=q;
4.复制线性链表(递归)
LinkListCopy(LinkListlista)
LinkListlistb;
if(lista==NULL)
returnNULL;
else{
listb=(LinkList)malloc(sizeof(LNode));
listb->data=lista->data;
listb->next=Copy(lista->next);
returnlistb;
5.将两个按值有序排列的非空线性链表合并为一个按值有序的线性链表
LinkListMergeList(LinkListlista,LinkListlistb)
LinkListlistc,p=lista,q=listb,r;
//listc指向lista和listb所指结点中较小者
if(lista->data<=listb->data){
listc=lista;
r=lista;
p=lista->next;
listc=listb;
r=listb;
q=listb->next;
=NULL&&q!
if(p->data<=q->data){
r->next=p;
r=p;
r->next=q;
q=q->next;
//将剩余结点(即未参加比较的且已按升序排列的结点)链接到整个链表后面
r->next=(p!
=NULL)?
p:
q;
returnlistc;
二、树
1.二叉树的先序遍历(非递归算法)
若
p所指结点不为空,则访问该结点,然后将该结点的地址入栈,然后再将
p指向其左孩
子结点;若
p所指向的结点为空,则从堆栈中退出栈顶元素(某个结点的地址),将
p指向其右孩子
结点。
重复上述过程,直到
p=NULL且堆栈为空,遍历结束。
#defineMAX_STACK50
voidPreOrderTraverse(BTreeT)
BTreeSTACK[MAX_STACK],p=T;
inttop=-1;
=NULL||top!
=-1)
VISIT(p);
STACK[++top]=p;
p=p->lchild;
p=STACK[top--];
p=p->rchild;
2.二叉树的中序遍历(非递归算法)
p所指结点不为空,则将该结点的地址
p入栈,然后再将
p指向其左孩子结点;若
p所
指向的结点为空,则从堆栈中退出栈顶元素(某个结点的地址)送
p,并访问该结点,然后再将
p指
向该结点的右孩子结点。
voidInOrderTraverse(BTreeT)
=-1);
3.二叉树的后序遍历(非递归算法)
当
p指向某一结点时,不能马上对它进行访问,而要先访问它的左子树,因而要将此结点
的地址入栈;当其左子树访问完毕后,再次搜索到该结点时(该结点地址通过退栈得到),还不能对
它进行访问,还需要先访问它的右子树,所以,再一次将该结点的地址入栈。
只有当该结点的右子
树访问完毕后回到该结点时,才能访问该结点。
为了标明某结点是否可以访问,引入一个标志变量
flag,当
flag=0时表示该结点暂不访问,
flag=1时表示该结点可以访问。
flag的值随同该结点的地
址一起入栈和出栈。
因此,算法中设置了两个堆栈,其中
STACK1存放结点的地址,STACK2存放
标志变量
flag,两个堆栈使用同一栈顶指针
top,且
top的初始值为
.1。
voidPostOrderTraverse(BTreeT)
BTreeSTACK1[MAX_STACK],p=T;
intSTACK2[MAX_STACK],flag,top=-1;
=NULL){
STACK1[++top]=p;
STACK2[top]=0;
p=STACK1[top];
flag=STACK2[top--];
if(flag==0){
STACK2[top]=1;
p=NULL;
4.二叉树的按层次遍历
设置一个队列,首先将根结点(的地址)入队列,然后依次从队列中退出一个元素,每
退出一个元素,先访问该元素所指的结点,然后依次将该结点的左孩子结点(若存在的话)和右孩
子结点(若存在的话)入队列。
如此重复下去,直到队列为空。
#defineMAX_QUEUE50
voidLayeredOrderTraverse(BTreeT)
BTreeQUEUE[MAX_QUEUE],p;
intfront,rear;
if(T!
QUEUE[0]=T;
front=-1;
rear=0;
while(front{p=QUEUE[++front];VISIT(P);if(p->lchild!=NULL)QUEUE[++rear]=p->lchild;if(p->rchild!=NULL)QUEUE[++rear]=p->rchild;}}}5.建立二叉树(从键盘输入数据,先序遍历递归算法)BTreeCreateBT(){charch;BTreeT;sacnf("%c",&ch);if(ch=='')returnNULL;else{T=(BTree)malloc(sizeof(BTNode));T->data=ch;T->lchild=CreateBT();T->rchild=CreateBT();returnT;}}6.建立二叉树(从数组获取数据)BTreeCreateBT(intA[],inti,intn){BTreep;if(i>n)returnNULL;else{p=(BTree)malloc(sizeof(BTNode));p->data=A[i];p->lchild=CreateBT(A,2*i,n);p->rchild=CreateBT(A,2*i+1,n);returnp;}}T=CreateBT(A,1,n);BTreeCreateBT(intA[],intn){inti;BTree*pT;//对应n个结点申请可容纳n个指针变量的内存空间pT=(BTree*)malloc(sizeof(BTree)*n);//若数组中的某个元素不等于零,则申请相应的结点空间并进行赋值for(i=1;i<=n;i++){if(A[i]!=0){pT[i]=(BTree)malloc(sizeof(BTNode));pT[i]->data=A[i];}else{pT[i]=NULL;}}//修改结点的指针域的内容,使父结点指向左、右孩子结点for(i=1;i<=n;i++){if(pT[i]!=NULL){pT[i]->lchild=pT[2*i];pT[i]->rchild=pT[2*i+1];}}}7.求二叉树的深度(递归算法)intDepth(BTreeT){intldepth,rdepth;if(T==NULL)return0;else{ldepth=Depth(T->lchild);rdepth=Depth(T->rchild);if(ldepth>rdepth)returnldepth+1;elsereturnrdepth+1;}}8.求二叉树的深度(非递归算法)算法思想:对二叉树进行遍历,遍历过程中依次记录各个结点所处的层次数以及当前已经访问过的结点所处的最大层次数。每当访问到某个叶子结点时,将该叶子结点所处的层次数与最大层次数进行比较,若前者大于后者,则修改最大层次数为该叶子结点的层次数,否则不作修改。遍历结束时,所记录的最大层次数即为该二叉树的深度。本算法使用的是非递归的中序遍历算法(其它遍历顺序也可以)。#defineMAX_STACK50intDepth(BTreeT){BTreeSTACK1[MAX_STACK],p=T;intSTACK2[MAX_STACK];intcurdepth,maxdepth=0,top=-1;if(T!=NULL){curdepth=1;while(p!=NULL||top!=-){while(p!=NULL){STACK1[++top]=p;STACK2[top]=curdepth;p=p->lchild;curdepth++;}p=STACK1[top];curdepth=STACK2[top--];if(p->lchild==NULL&&p->rchild==NULL)if(curdepth>maxdepth)maxdepth=curdepth;p=p->rchild;curdepth++;}}returnmaxdepth;}9.求结点所在层次算法思想:采用后序遍历的非递归算法对二叉树进行遍历,遍历过程中对每一个结点判断其是否为满足条件的结点,若是满足条件的结点,则此时堆栈中保存的元素个数再加1即为该结点所在的层次。#defineMAX_STACK50intLayerNode(BTreeT,intitem){BTreeSTACK1[MAX_STACK],p=T;intSTACK2[MAX_STACK],flag,top=-1;while(p!=NULL||top!=-1){while(p!=NULL){STACK1[++top]=p;STACK2[top]=0;p=p->lchild;}p=STACK1[top];flag=STACK2[top--];if(flag==0){STACK1[++top]=p;STACK2[top]=1;p=p->rchild;}else{if(p->data==item)returntop+2;p=NULL;}}}10.交换二叉树中所有结点的左右子树的位置算法思想:按层次遍历二叉树,遍历过程中每当访问一个结点时,就将该结点的左右子树的位置对调。#defineMAX_QUEUE50voidExchangeBT(BTreeT){BTreeQUEUE[MAX_QUEUE],temp,p=T;intfront,rear;if(T!=NULL){QUEUE[0]=T;front=-1;rear=0;while(front{p=QUEUE[++front];temp=p->lchild;p->lchild=p->rchild;p->rchild=temp;if(p->lchild!=NULL)QUEUE[++rear]=p->lchild;if(p->rchild!=NULL)QUEUE[++rear]=p->rchild;}}}11.删除二叉树中以某个结点为根结点的子树算法思想:先序遍历找到符合条件的结点(其它遍历方法亦可),然后删除以该结点为根结点的子树。最后把该结点的父结点的相应的指针域置为NULL。为此,需在算法中设置一个指针变量用以指示当前结点的父结点。#defineMAX_STACK50BTreeDeleteSubtree(BTree&T,intitem){BTreeSTACK[MAX_STACK],q,p=T;inttop=-1;if(T->data==item){DestroyBT(T);T=NULL;returnNULL;}else{while(p!=NULL||top!=-1){while(p!=NULL){if(p->data==item){if(q->lchild==p)q->lchild=NULL;elseq->rchild=NULL;DestroyBT(p);returnT;}STACK[++top]=p;q=p;p=p->lchild;}q=STACK[top--];p=q->rchild;}}}三、查找1.顺序查找的递归算法intRecurSeqSearch(intA[],intn,intkey,inti){if(i>=n)return-1;if(A[i]==key)returni;elsereturnRecurSeqSearch(A,n,key,i+1);}pos=RecurSeqSearch(A,n,key,0);2.折半查找intBinSearch(intA[],intn,intkey){intlow=0,high=n-1,mid;while(low<=high){mid=(low+high)/2;if(key==A[mid])returnmid;if(key>A[mid])low=mid+1;elsehigh=mid–1;}return-1;}3.折半查找的递归算法intRecurBinSearch(intA[],intlow,inthigh,intkey){intmid;if(low>high)return-1;else{mid=(low+high)/2;if(key==A[mid])returnmid;if(key>A[mid])returnRecurBinSearch(A,mid+1,high,key);elsereturnRecurBinSearch(A,low,mid-1,key);}}pos=RecurBinSearch(A,0,n-1,key);4.在按值递增排列且长度为n的线性表中折半查找并插入一元素voidBinInsert(intA[],int&n,intkey){intj,low=0,high=n-1,mid;while(low<=high){mid=(low+high)/2;if(key>A[mid])low=mid+1;elsehigh=mid–1;}for(j=n;j>low;j--)A[j]=A[j-1];A[low]=key;n++;}5.在按值递增排列且长度为n的线性表中折半查找值不小于key的最小元素voidBinSearch(intA[],intn,intkey){intlow=0,high=n-1,mid;while(low<=high){mid=(low+high)/2;if(key==A[mid])returnmid;if(key>A[mid])low=mid+1;elsehigh=mid–1;}if(low<=n-1)returnlow;elsereturn-1;}四、排序1.插入排序算法思想:第i趟插入排序为:在含有i.1个元素的有序子序列中插入一个元素,使之成为含有i个元素的有序子序列。在查找插入位置的过程中,可以同时后移元素。整个过程为进行n.1趟插入,即先将整个序列的第1个元素看成是有序的,然后从第2个元素起逐个进行插入,直到整个序列有序为止。voidInsertSort(intA[],intn){inti,j,temp;for(i=1;i<=n-1;i++){if(A[i]{j=i-1;temp=A[i];while(j>=0&&temp{A[j+1]=A[j];j--;}A[j+1]=temp;}}}2.折半插入排序算法思想:算法同直接插入排序,只不过使用折半查找的方法来寻找插入位置。voidBinInsertSort(intA[],intn){inti,j,low,high,mid,temp;for(i=1;i<=n-1;i++){temp=A[i];low=0;high=i–1;while(low<=high){mid=(low+high)/2;if(temp>A[mid])low=mid+1;elsehigh=mid–1;}for(j=i;j>low;j--)A[j]=A[j-1];A[low]=temp;}}3.冒泡排序算法思想:首先将第1个元素和第2个元素进行比较,若前者大于后者,则两者交换位置,然后比较第2个元素和第3个元素。依此类推,直到第n.1个元素和第n个元素进行过比较或交换为止。上述过程称为一趟冒泡排序,其结果是使得n个元素中值最大的那个元素被安排在最后一个元素的位置上。然后进行第二趟排序,即对前n.1个元素进行同样的操作,使得前n.1个元素中值最大的那个元素被安排在第n.1个位置上。一般地,第i趟冒泡排序是从前n.i+1个元素中的第1个元素开始,两两比较,若前者大于后者,则交换,结果使得前n.i+1个元素中最大的元素被安排在第n.i+1个位置上。显然,判断冒泡排序结束的条件是“在一趟排序中没有进行过交换元素的操作”,为此,设立一个标志变量flag,flag=1表示有过交换元素的操作,flag=0表示没有过交换元素的操作,在每一趟排序开始前,将flag置为0,在排序过程中,只要有交换元素的操作,就及时将flag置为1。因为至少要执行一趟排序操作,故第一趟排序时,flag=1。voidBubbleSort(intA[],intn){inti,j,
p=QUEUE[++front];
VISIT(P);
if(p->lchild!
QUEUE[++rear]=p->lchild;
if(p->rchild!
QUEUE[++rear]=p->rchild;
5.建立二叉树(从键盘输入数据,先序遍历递归算法)
BTreeCreateBT()
charch;
BTreeT;
sacnf("%c",&ch);
if(ch=='')
T=(BTree)malloc(sizeof(BTNode));
T->data=ch;
T->lchild=CreateBT();
T->rchild=CreateBT();
returnT;
6.建立二叉树(从数组获取数据)
BTreeCreateBT(intA[],inti,intn)
BTreep;
if(i>n)
p=(BTree)malloc(sizeof(BTNode));
p->data=A[i];
p->lchild=CreateBT(A,2*i,n);
p->rchild=CreateBT(A,2*i+1,n);
returnp;
T=CreateBT(A,1,n);
BTreeCreateBT(intA[],intn)
inti;
BTree*pT;
//对应
n个结点申请可容纳
n个指针变量的内存空间
pT=(BTree*)malloc(sizeof(BTree)*n);
//若数组中的某个元素不等于零,则申请相应的结点空间并进行赋值
for(i=1;i<=n;i++)
if(A[i]!
=0){
pT[i]=(BTree)malloc(sizeof(BTNode));
pT[i]->data=A[i];
pT[i]=NULL;
//修改结点的指针域的内容,使父结点指向左、右孩子结点
if(pT[i]!
pT[i]->lchild=pT[2*i];
pT[i]->rchild=pT[2*i+1];
7.求二叉树的深度(递归算法)
intDepth(BTreeT)
intldepth,rdepth;
if(T==NULL)
return0;
ldepth=Depth(T->lchild);
rdepth=Depth(T->rchild);
if(ldepth>rdepth)
returnldepth+1;
else
returnrdepth+1;
8.求二叉树的深度(非递归算法)
对二叉树进行遍历,遍历过程中依次记录各个结点所处的层次数以及当前已经访问过的
结点所处的最大层次数。
每当访问到某个叶子结点时,将该叶子结点所处的层次数与最大层次数进
行比较,若前者大于后者,则修改最大层次数为该叶子结点的层次数,否则不作修改。
遍历结束时,
所记录的最大层次数即为该二叉树的深度。
本算法使用的是非递归的中序遍历算法(其它遍历顺序
也可以)。
intSTACK2[MAX_STACK];
intcurdepth,maxdepth=0,top=-1;
curdepth=1;
=-)
STACK2[top]=curdepth;
curdepth++;
curdepth=STACK2[top--];
if(p->lchild==NULL&&p->rchild==NULL)
if(curdepth>maxdepth)
maxdepth=curdepth;
returnmaxdepth;
9.求结点所在层次
采用后序遍历的非递归算法对二叉树进行遍历,遍历过程中对每一个结点判断其是否为
满足条件的结点,若是满足条件的结点,则此时堆栈中保存的元素个数再加
1即为该结点所在的层次。
intLayerNode(BTreeT,intitem)
if(p->data==item)
returntop+2;
10.交换二叉树中所有结点的左右子树的位置
按层次遍历二叉树,遍历过程中每当访问一个结点时,就将该结点的左右子树的位置对
调。
voidExchangeBT(BTreeT)
BTreeQUEUE[MAX_QUEUE],temp,p=T;
while(front{p=QUEUE[++front];temp=p->lchild;p->lchild=p->rchild;p->rchild=temp;if(p->lchild!=NULL)QUEUE[++rear]=p->lchild;if(p->rchild!=NULL)QUEUE[++rear]=p->rchild;}}}11.删除二叉树中以某个结点为根结点的子树算法思想:先序遍历找到符合条件的结点(其它遍历方法亦可),然后删除以该结点为根结点的子树。最后把该结点的父结点的相应的指针域置为NULL。为此,需在算法中设置一个指针变量用以指示当前结点的父结点。#defineMAX_STACK50BTreeDeleteSubtree(BTree&T,intitem){BTreeSTACK[MAX_STACK],q,p=T;inttop=-1;if(T->data==item){DestroyBT(T);T=NULL;returnNULL;}else{while(p!=NULL||top!=-1){while(p!=NULL){if(p->data==item){if(q->lchild==p)q->lchild=NULL;elseq->rchild=NULL;DestroyBT(p);returnT;}STACK[++top]=p;q=p;p=p->lchild;}q=STACK[top--];p=q->rchild;}}}三、查找1.顺序查找的递归算法intRecurSeqSearch(intA[],intn,intkey,inti){if(i>=n)return-1;if(A[i]==key)returni;elsereturnRecurSeqSearch(A,n,key,i+1);}pos=RecurSeqSearch(A,n,key,0);2.折半查找intBinSearch(intA[],intn,intkey){intlow=0,high=n-1,mid;while(low<=high){mid=(low+high)/2;if(key==A[mid])returnmid;if(key>A[mid])low=mid+1;elsehigh=mid–1;}return-1;}3.折半查找的递归算法intRecurBinSearch(intA[],intlow,inthigh,intkey){intmid;if(low>high)return-1;else{mid=(low+high)/2;if(key==A[mid])returnmid;if(key>A[mid])returnRecurBinSearch(A,mid+1,high,key);elsereturnRecurBinSearch(A,low,mid-1,key);}}pos=RecurBinSearch(A,0,n-1,key);4.在按值递增排列且长度为n的线性表中折半查找并插入一元素voidBinInsert(intA[],int&n,intkey){intj,low=0,high=n-1,mid;while(low<=high){mid=(low+high)/2;if(key>A[mid])low=mid+1;elsehigh=mid–1;}for(j=n;j>low;j--)A[j]=A[j-1];A[low]=key;n++;}5.在按值递增排列且长度为n的线性表中折半查找值不小于key的最小元素voidBinSearch(intA[],intn,intkey){intlow=0,high=n-1,mid;while(low<=high){mid=(low+high)/2;if(key==A[mid])returnmid;if(key>A[mid])low=mid+1;elsehigh=mid–1;}if(low<=n-1)returnlow;elsereturn-1;}四、排序1.插入排序算法思想:第i趟插入排序为:在含有i.1个元素的有序子序列中插入一个元素,使之成为含有i个元素的有序子序列。在查找插入位置的过程中,可以同时后移元素。整个过程为进行n.1趟插入,即先将整个序列的第1个元素看成是有序的,然后从第2个元素起逐个进行插入,直到整个序列有序为止。voidInsertSort(intA[],intn){inti,j,temp;for(i=1;i<=n-1;i++){if(A[i]{j=i-1;temp=A[i];while(j>=0&&temp{A[j+1]=A[j];j--;}A[j+1]=temp;}}}2.折半插入排序算法思想:算法同直接插入排序,只不过使用折半查找的方法来寻找插入位置。voidBinInsertSort(intA[],intn){inti,j,low,high,mid,temp;for(i=1;i<=n-1;i++){temp=A[i];low=0;high=i–1;while(low<=high){mid=(low+high)/2;if(temp>A[mid])low=mid+1;elsehigh=mid–1;}for(j=i;j>low;j--)A[j]=A[j-1];A[low]=temp;}}3.冒泡排序算法思想:首先将第1个元素和第2个元素进行比较,若前者大于后者,则两者交换位置,然后比较第2个元素和第3个元素。依此类推,直到第n.1个元素和第n个元素进行过比较或交换为止。上述过程称为一趟冒泡排序,其结果是使得n个元素中值最大的那个元素被安排在最后一个元素的位置上。然后进行第二趟排序,即对前n.1个元素进行同样的操作,使得前n.1个元素中值最大的那个元素被安排在第n.1个位置上。一般地,第i趟冒泡排序是从前n.i+1个元素中的第1个元素开始,两两比较,若前者大于后者,则交换,结果使得前n.i+1个元素中最大的元素被安排在第n.i+1个位置上。显然,判断冒泡排序结束的条件是“在一趟排序中没有进行过交换元素的操作”,为此,设立一个标志变量flag,flag=1表示有过交换元素的操作,flag=0表示没有过交换元素的操作,在每一趟排序开始前,将flag置为0,在排序过程中,只要有交换元素的操作,就及时将flag置为1。因为至少要执行一趟排序操作,故第一趟排序时,flag=1。voidBubbleSort(intA[],intn){inti,j,
temp=p->lchild;
p->lchild=p->rchild;
p->rchild=temp;
11.删除二叉树中以某个结点为根结点的子树
先序遍历找到符合条件的结点(其它遍历方法亦可),然后删除以该结点为根结点的子树。
最后把该结点的父结点的相应的指针域置为
NULL。
为此,需在算法中设置一个指针变量用以指示当
前结点的父结点。
BTreeDeleteSubtree(BTree&T,intitem)
BTreeSTACK[MAX_STACK],q,p=T;
if(T->data==item)
DestroyBT(T);
T=NULL;
if(q->lchild==p)
q->lchild=NULL;
q->rchild=NULL;
DestroyBT(p);
q=STACK[top--];
p=q->rchild;
三、查找
1.顺序查找的递归算法
intRecurSeqSearch(intA[],intn,intkey,inti)
if(i>=n)
return-1;
if(A[i]==key)
returni;
returnRecurSeqSearch(A,n,key,i+1);
pos=RecurSeqSearch(A,n,key,0);
2.折半查找
intBinSearch(intA[],intn,intkey)
intlow=0,high=n-1,mid;
while(low<=high)
mid=(low+high)/2;
if(key==A[mid])
returnmid;
if(key>A[mid])
low=mid+1;
high=mid–1;
3.折半查找的递归算法
intRecurBinSearch(intA[],intlow,inthigh,intkey)
intmid;
if(low>high)
returnRecurBinSearch(A,mid+1,high,key);
returnRecurBinSearch(A,low,mid-1,key);
pos=RecurBinSearch(A,0,n-1,key);
4.在按值递增排列且长度为
n的线性表中折半查找并插入一元素
voidBinInsert(intA[],int&n,intkey)
intj,low=0,high=n-1,mid;
for(j=n;j>low;j--)
A[j]=A[j-1];
A[low]=key;
n++;
5.在按值递增排列且长度为
n的线性表中折半查找值不小于
key的最小元素
voidBinSearch(intA[],intn,intkey)
if(low<=n-1)
returnlow;
四、排序
1.插入排序
第
i趟插入排序为:
在含有
i.1个元素的有序子序列中插入一个元素,使之成为含有
i
个元素的有序子序列。
在查找插入位置的过程中,可以同时后移元素。
整个过程为进行
n.1趟插入,
即先将整个序列的第
1个元素看成是有序的,然后从第
2个元素起逐个进行插入,直到整个序列有序
为止。
voidInsertSort(intA[],intn)
inti,j,temp;
for(i=1;i<=n-1;i++)
if(A[i]{j=i-1;temp=A[i];while(j>=0&&temp{A[j+1]=A[j];j--;}A[j+1]=temp;}}}2.折半插入排序算法思想:算法同直接插入排序,只不过使用折半查找的方法来寻找插入位置。voidBinInsertSort(intA[],intn){inti,j,low,high,mid,temp;for(i=1;i<=n-1;i++){temp=A[i];low=0;high=i–1;while(low<=high){mid=(low+high)/2;if(temp>A[mid])low=mid+1;elsehigh=mid–1;}for(j=i;j>low;j--)A[j]=A[j-1];A[low]=temp;}}3.冒泡排序算法思想:首先将第1个元素和第2个元素进行比较,若前者大于后者,则两者交换位置,然后比较第2个元素和第3个元素。依此类推,直到第n.1个元素和第n个元素进行过比较或交换为止。上述过程称为一趟冒泡排序,其结果是使得n个元素中值最大的那个元素被安排在最后一个元素的位置上。然后进行第二趟排序,即对前n.1个元素进行同样的操作,使得前n.1个元素中值最大的那个元素被安排在第n.1个位置上。一般地,第i趟冒泡排序是从前n.i+1个元素中的第1个元素开始,两两比较,若前者大于后者,则交换,结果使得前n.i+1个元素中最大的元素被安排在第n.i+1个位置上。显然,判断冒泡排序结束的条件是“在一趟排序中没有进行过交换元素的操作”,为此,设立一个标志变量flag,flag=1表示有过交换元素的操作,flag=0表示没有过交换元素的操作,在每一趟排序开始前,将flag置为0,在排序过程中,只要有交换元素的操作,就及时将flag置为1。因为至少要执行一趟排序操作,故第一趟排序时,flag=1。voidBubbleSort(intA[],intn){inti,j,
j=i-1;
temp=A[i];
while(j>=0&&temp{A[j+1]=A[j];j--;}A[j+1]=temp;}}}2.折半插入排序算法思想:算法同直接插入排序,只不过使用折半查找的方法来寻找插入位置。voidBinInsertSort(intA[],intn){inti,j,low,high,mid,temp;for(i=1;i<=n-1;i++){temp=A[i];low=0;high=i–1;while(low<=high){mid=(low+high)/2;if(temp>A[mid])low=mid+1;elsehigh=mid–1;}for(j=i;j>low;j--)A[j]=A[j-1];A[low]=temp;}}3.冒泡排序算法思想:首先将第1个元素和第2个元素进行比较,若前者大于后者,则两者交换位置,然后比较第2个元素和第3个元素。依此类推,直到第n.1个元素和第n个元素进行过比较或交换为止。上述过程称为一趟冒泡排序,其结果是使得n个元素中值最大的那个元素被安排在最后一个元素的位置上。然后进行第二趟排序,即对前n.1个元素进行同样的操作,使得前n.1个元素中值最大的那个元素被安排在第n.1个位置上。一般地,第i趟冒泡排序是从前n.i+1个元素中的第1个元素开始,两两比较,若前者大于后者,则交换,结果使得前n.i+1个元素中最大的元素被安排在第n.i+1个位置上。显然,判断冒泡排序结束的条件是“在一趟排序中没有进行过交换元素的操作”,为此,设立一个标志变量flag,flag=1表示有过交换元素的操作,flag=0表示没有过交换元素的操作,在每一趟排序开始前,将flag置为0,在排序过程中,只要有交换元素的操作,就及时将flag置为1。因为至少要执行一趟排序操作,故第一趟排序时,flag=1。voidBubbleSort(intA[],intn){inti,j,
A[j+1]=A[j];
j--;
A[j+1]=temp;
2.折半插入排序
算法同直接插入排序,只不过使用折半查找的方法来寻找插入位置。
voidBinInsertSort(intA[],intn)
inti,j,low,high,mid,temp;
low=0;
high=i–1;
if(temp>A[mid])
for(j=i;j>low;j--)
A[low]=temp;
3.冒泡排序
首先将第
1个元素和第
2个元素进行比较,若前者大于后者,则两者交换位置,然后比较
2个元素和第
3个元素。
依此类推,直到第
n.1个元素和第
n个元素进行过比较或交换为止。
上
述过程称为一趟冒泡排序,其结果是使得
n个元素中值最大的那个元素被安排在最后一个元素的位置
上。
然后进行第二趟排序,即对前
n.1个元素进行同样的操作,使得前
n.1个元素中值最大的那
个元素被安排在第
n.1个位置上。
一般地,第
i趟冒泡排序是从前
n.
i+1个元素中的第
1个元素
开始,两两比较,若前者大于后者,则交换,结果使得前
n.i+1个元素中最大的元素被安排在第
n
.
i+1个位置上。
显然,判断冒泡排序结束的条件是“在一趟排序中没有进行过交换元素的操作”,
为此,设立一个标志变量
flag,flag=1表示有过交换元素的操作,
flag=0表示没有过交换元素的操
作,在每一趟排序开始前,将
flag置为
0,在排序过程中,只要有交换元素的操作,就及时将
flag置
为
1。
因为至少要执行一趟排序操作,故第一趟排序时,
flag=1。
voidBubbleSort(intA[],intn)
inti,j,
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1