版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
數(shù)據(jù)結構算法背誦
一、線性表
1.逆轉順序表中的所有元素
算法思想:第一個元素和最后一個元素對調,第二個元素和倒數(shù)第二
個元素對調,……,依此類推。
voidReverse(intA[],intn)
(
inti,t;
for(i=0;i<n/2;i++)
(
t=A[i];
A[i]=A[n-i-l];
A[n-i-lJ=t;
)
)
2.刪除線性鏈表中數(shù)據(jù)域為
item的所有結點
算法思想:先從鏈表的第
2個結點開始,從前往后依次判斷鏈表中的所有結點是否滿足條件,
若某個
結點的數(shù)據(jù)域為
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!=NULLIItop!=-l)
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!=NULLIItop!=-l);
(
while(p!=NULL)
(
STACK[++top]=p;
p=p->lchild;
)
p=STACK[top-];
VISIT(p);
p=p->rchild;
3.二叉樹的后序遍歷(非遞歸算法)
算法思想:當
P指向某一結點時,不能馬上對它進行訪問,而要先訪問它的左子樹,
因而要將此結點
的地址入棧;當其左子樹訪問完畢后,再次搜索到該結點時(該結點
地址通過退棧得到),還不能對
它進行訪問,還需要先訪問它的右子樹,所以,再一次將該結點的地
址入棧。只有當該結點的右子
樹訪問完畢后回到該結點時,才能訪問該結點。為了標明某結點是否
可以訪問,引入一個標志變量
flag,當
flag=O時表示該結點暫不訪問,
flag=1時表示該結點可以訪問。flag的值隨同該結點的地
址一起入棧和出棧。因此,算法中設置了兩個堆棧,其中
STACK1存放結點的地址,STACK2存放
標志變量
flag,兩個堆棧使用同一棧頂指針
top,且
top的初始值為
.lo
#defineMAX_STACK50
voidPostOrderTraverse(BTreeT)
BTreeSTACK1[MAX_STACKJ,p=T;
intSTACK2[MAX_STACK],flag,top=-1;
while(p!=NULLIItop!=-l)
while(p!=NULL){
STACKl[++top]=p;
STACK2[top]=0;
p=p->lchild;
p=STACK1[top];
flag=STACK2[top-];
if(flag==0){
STACKl[++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<rear)
p=QUEUE[++front];
VISIT(P);
if(p->lchild!=NULL)
QUEUE[++rear]=p->lchild;
if(p->rchild!=NULL)
QUEUE[++rearJ=p->rchild;
5.建立二叉樹(從鍵盤輸入數(shù)據(jù),先序遍歷遞歸算法)
BTreeCreateBT()
charch;
BTreeT;
sacnf("%c",&ch);
if(ch==")
returnNULL;
else{
T=(BTree)malloc(sizeof(BTNode));
T->data=ch;
T->Ichild=CreateBT();
T->rchild=CreateBT();
returnT;
6.建立二叉樹(從數(shù)組獲取數(shù)據(jù))
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+l,n);
returnp;
)
)
T=CreateBT(A,1,n);
BTreeCreateBT(intA[],intn)
inti;
BTree*pT;
//對應
n個結點申請可容納
n個指針變量的內存空間
pT=(BTree*)malloc(sizeof(BTree)*n);
//若數(shù)組中的某個元素不等于零,則申請相應的結點空間并進行賦值
for(i=l;i<=n;i++)
if(A[i]!=0){
pT[i]=(BTree)malloc(sizeof(BTNode));
pT[i]->data=A[i];
}else{
pT[i]=NULL;
〃修改結點的指針域的內容,使父結點指向左、右孩子結點
for(i=l;i<=n;i++)
(
if(pT[i]!=NULL)
pT[i]->lchild=pT[2*i];
pT[i]->rchild=pT[2*i+l];
7.求二叉樹的深度(遞歸算法)
intDepth(BTreeT)
(
intIdepth,rdepth;
if(T==NULL)
return0;
else{
Idepth=Depth(T->lchild);
rdepth=Depth(T->rchild);
if(Idepth>rdepth)
returnldepth+1;
else
returnrdepth+1;
)
)
8.求二叉樹的深度(非遞歸算法)
算法思想:對二叉樹進行遍歷,遍歷過程中依次記錄各個結點所處的
層次數(shù)以及當前已經訪問過的
結點所處的最大層次數(shù)。每當訪問到某個葉子結點時,將該葉子結點
所處的層次數(shù)與最大層次數(shù)進
行比較,若前者大于后者,則修改最大層次數(shù)為該葉子結點的層次數(shù),
否則不作修改。遍歷結束時,
所記錄的最大層次數(shù)即為該二叉樹的深度。本算法使用的是非遞歸的
中序遍歷算法(其它遍歷順序
也可以)。
#defineMAX_STACK50
intDepth(BTreeT)
(
BTreeSTACK1[MAX_STACK],p=T;
intSTACK2[MAX_STACK];
intcurdepth,maxdepth=0,top=-1;
if(T!=NULL)
(
curdepth=1;
while(p!=NULLIItop!=-)
while(p!=NULL)
(
STACK1[++top]=p;
STACK2[top]=curdepth;
p=p->lchild;
curdepth++;
p=STACK1[top];
curdepth=STACK2[top—J;
if(p->lchild==NULL&&p->rchild==NULL)
if(curdepth>maxdepth)
maxdepth=curdepth;
p=p->rchild;
curdepth++;
)
)
returnmaxdepth;
9.求結點所在層次
算法思想:采用后序遍歷的非遞歸算法對二叉樹進行遍歷,遍歷過程
中對每一個結點判斷其是否為
滿足條件的結點,若是滿足條件的結點,則此時堆棧中保存的元素個
數(shù)再加
1即為該結點所在的層次。
#defineMAX_STACK50
intLayerNode(BTreeT,intitem)
BTreeSTACK1[MAX_STACK],p=T;
intSTACK2[MAX_STACK],flag,top=-l;
while(p!=NULLIItop!=-l)
while(p!=NULL)
STACKl[++top]=p;
STACK2[top]=0;
p=p->lchild;
p=STACK1[top];
flag=STACK2[top-];
if(flag==0){
STACKl[++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<rear)
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.刪除二叉樹中以某個結點為根結點的子樹
算法思想:先序遍歷找到符合條件的結點(其它遍歷方法亦可),然
后刪除以該結點為根結點的子樹。
最后把該結點的父結點的相應的指針域置為
NULLo為此,需在算法中設置一個指針變量用以指示當
前結點的父結點。
#defineMAX_STACK50
BTreeDeleteSubtree(BTree&T,intitem)
(
BTreeSTACK[MAX_STACK],q,p=T;
inttop=-1;
if(T->data==item)
(
DestroyBT(T);
T=NULL;
returnNULL;
I
else
while(p!=NULLIItop!=-l)
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的線性表中折半查找并插入一元素
voidBinlnsert(intA[],int&n,intkey)
(
intj,low=0,high=n-l,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--)
AU]=AU-1];
A[low]=key;
n++;
)
5.在按值遞增排列且長度為
n的線性表中折半查找值不小于
key的最小元素
voidBinSearch(intA[J,intn,intkey)
intlow=0,high=n-l,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=l;i<=n-1;i++)
if(A[i]<A[i-l])
j=i-l;
temp=A[i];
while(j>=0&&temp<A[j])
(
AU+l]=A[j];
j-s
)
A[j+1]=temp;
)
)
}
2.折半插入排序
算法思想:算法同直接插入排序,只不過使用折半查找的方法來尋找
插入位置。
voidBinInsertSort(intA[],intn)
(
inti,j,low,high,mid,temp;
for(i=l;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—)
AU]=AU-1];
A[low]=temp;
)
3.冒泡排序
算法思想:首先將第
1個元素和第
2個元素進行比較,若前者大于后者,則兩者交換位置,然后比較
第
2個元素和第
3個元素。依此類推,直到第
n.1個元素和第
n個元素進行過比較或交換為止。上
述過程稱為一趟冒泡排序,其結果是使得
n個元素中值最大的那個元素被安排在最后一個元素的位置
±o然后進行第二趟排序,即對前
n.l個元素進行同樣的操作,使得前
nJ個元素中值最大的那
個元素被安排在第
n.1個位置上。一般地,第
i趟冒泡排序是從前
n.
i+1個元素中的第
1個元素
開始,兩兩比較,若前者大于后者,則交換,結果使得前
n.i+1個元素中最大的元素被安排在第
i+1個位置上。顯然,判斷冒泡排序結束的條件是“在一趟排序中沒
有進行過交換元素的操作”,
為此,設立一個標志變量
flag,flag=1表示有過交換元素的操作,
flag=0表示沒有過交換元素的操
作,在每一趟排序開始前,將
flag置為
0,在排序過程中,只要有交換元素的操作,就及時將
flag置
為
lo因為至少要執(zhí)行一趟排序操作,故第一趟排序時,
flag=lo
voidBubbleSort(intA[],intn)
(
inti,j,temp,flag=1;
for(i=n-l;i>=1&&flag==1;i—)
(
flag=0;
for(j=O;j<i;j++)
if(A[j]>A[j+l])
temp=A[j];
A「]=AU+1];
A[j+1]=temp;
flag=1;
)
4.選擇排序
算法思想:第
i趟排序從序列的后
i+1(i=l,2,...,n.l)個元素中選擇一個值最小的元素與該
個元素的第
1個元素交換位置,即與整個序列的第
i個元素交換。依此類推,直到
i=n.1為止。也
就是說,每一趟排序從從未排好序的那些元素中選擇一個值最小的元
素,然后將其與這些未排好序
的元素中的第
1個元素交換位置。
voidSelectSort(intA[],intn)
inti,j,min,temp;
for(i=0;i<n;i++)
min=1;
for(j=i+l;j<n;j++)
if(A[min]>A[j])
min=j;
)
if(min!=i)
temp=A[min];
A[min]=A[i];
A[i]=temp;
5.快速排序
算法思想:在參加排序的序列中任意選擇一個元素(通常稱為分界元
素或基準元素),把小于或等于
分界元素的所有元素都移到分界元素的前面,把大于分界元素的所有
元素都移到
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年庫房轉租合同轉租條件、轉租手續(xù)及租金處理分析
- 2024年企業(yè)內部審計保密協(xié)議
- 2024年度企業(yè)社會責任報告合同
- 2024年度住宅小區(qū)木門安裝工程合同
- 2024年度許可使用合同(商標)
- 腰椎ct課件教學課件
- 2024北京技術合同
- 2024年大數(shù)據(jù)使用協(xié)議:數(shù)據(jù)收集、分析和應用的具體規(guī)定
- 液體密度課件教學課件
- 輿論學課件教學
- 入團志愿書(2016版本)(可編輯打印標準A4) (1)
- 專項基金投資募集合作框架協(xié)議模版
- 浙江省公路山嶺隧道機械化裝備應用指導手冊
- (完整word版)拼音練習jqx和ü、üe的相拼
- 醫(yī)療質量檢查分析、總結、反饋5篇
- 桅桿工藝技術及施工要求
- (完整版)六年級下冊體育教學計劃與教案
- 北京地鐵受電弓的維護與故障檢修-畢業(yè)設計說明書
- 幼兒園教育和家庭教育的有效結合研究
- 集團公司兩金管理評價辦法
- 電影的聲音分析PPT課件
評論
0/150
提交評論