数据结构算法背诵版.docx

上传人:b****6 文档编号:6673443 上传时间:2023-01-08 格式:DOCX 页数:25 大小:20.31KB
下载 相关 举报
数据结构算法背诵版.docx_第1页
第1页 / 共25页
数据结构算法背诵版.docx_第2页
第2页 / 共25页
数据结构算法背诵版.docx_第3页
第3页 / 共25页
数据结构算法背诵版.docx_第4页
第4页 / 共25页
数据结构算法背诵版.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

数据结构算法背诵版.docx

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

数据结构算法背诵版.docx

数据结构算法背诵版

数据结构算法背诵

一、线性表

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_STACK50

voidPreOrderTraverse(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_STACK50

voidInOrderTraverse(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_STACK50

voidPostOrderTraverse(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_QUEUE50

voidLayeredOrderTraverse(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;

else

returnrdepth+1;

}

}

8.求二叉树的深度(非递归算法)

算法思想:

对二叉树进行遍历,遍历过程中依次记录各个结点所处的层次数以及当前已经访问过的

结点所处的最大层次数。

每当访问到某个叶子结点时,将该叶子结点所处的层次数与最大层次数进

行比较,若前者大于后者,则修改最大层次数为该叶子结点的层次数,否则不作修改。

遍历结束时,

所记录的最大层次数即为该二叉树的深度。

本算法使用的是非递归的中序遍历算法(其它遍历顺序

也可以)。

#defineMAX_STACK50

intDepth(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_STACK50

intLayerNode(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_QUEUE50

voidExchangeBT(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_STACK50

BTreeDeleteSubtree(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;

else

q->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;

else

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;

else

high=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);

else

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;

while(low<=high)

{

mid=(low+high)/2;

if(key>A[mid])

low=mid+1;

else

high=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;

else

high=mid–1;

}

if(low<=n-1)

returnlow;

else

return-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;

else

high=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,

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

当前位置:首页 > 解决方案 > 学习计划

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

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