1. 清華大學嚴蔚敏數據結構題集完整答案(c語言版)
第一章 緒論
1.16
void print_descending(int x,int y,int z)//按從大到小順序輸出三個數
{
scanf("%d,%d,%d",&x,&y,&z);
if(x<y) x<->y; //<->為表示交換的雙目運算符,以下同
if(y<z) y<->z;
if(x<y) x<->y; //冒泡排序
printf("%d %d %d",x,y,z);
}//print_descending
1.17
Status fib(int k,int m,int &f)//求k階斐波那契序列的第m項的值f
{
int tempd;
if(k<2||m<0) return ERROR;
if(m<k-1) f=0;
else if (m==k-1) f=1;
else
{
for(i=0;i<=k-2;i++) temp[i]=0;
temp[k-1]=1; //初始化
for(i=k;i<=m;i++) //求出序列第k至第m個元素的值
{
sum=0;
for(j=i-k;j<i;j++) sum+=temp[j];
temp[i]=sum;
}
f=temp[m];
}
return OK;
}//fib
分析:通過保存已經計算出來的結果,此方法的時間復雜度僅為O(m^2).如果採用遞歸編程(大多數人都會首先想到遞歸方法),則時叢盯間復雜度將高達O(k^m).
1.18
typedef struct{
char *sport;
enum{male,female} gender;
char schoolname; //校名為'A','B','C','D'或'E'
char *result;
int score;
} resulttype;
typedef struct{
int malescore;
int femalescore;
int totalscore;
} scoretype;
void summary(resulttype result[ ])//求各校的男女總分和團體總圓笑分,假設結果已經儲存在result[ ]數組中
{
scoretype score ;
i=0;
while(result[i].sport!=NULL)
{
switch(result[i].schoolname)
{
case 'A':
score[ 0 ].totalscore+=result[i].score;
if(result[i].gender==0) score[ 0 ].malescore+=result[i].score;
else score[ 0 ].femalescore+=result[i].score;
break;
case 'B':
score .totalscore+=result[i].score;
if(result[i].gender==0) score .malescore+=result[i].score;
else score .femalescore+=result[i].score;
break;
…… …… ……
}
i++;
}
for(i=0;i<5;i++)
{
printf("School %d:\n",i);
printf("Total score of male:%d\n",score[i].malescore);
printf("Total score of female:%d\n",score[i].femalescore);
printf("Total score of all:%d\n\橘鄭含n",score[i].totalscore);
}
}//summary
1.19
Status algo119(int a[ARRSIZE])//求i!*2^i序列的值且不超過maxint
{
last=1;
for(i=1;i<=ARRSIZE;i++)
{
a[i-1]=last*2*i;
if((a[i-1]/last)!=(2*i)) reurn OVERFLOW;
last=a[i-1];
return OK;
}
}//algo119
分析:當某一項的結果超過了maxint時,它除以前面一項的商會發生異常.
1.20
void polyvalue()
{
float ad;
float *p=a;
printf("Input number of terms:");
scanf("%d",&n);
printf("Input the %d coefficients from a0 to a%d:\n",n,n);
for(i=0;i<=n;i++) scanf("%f",p++);
printf("Input value of x:");
scanf("%f",&x);
p=a;xp=1;sum=0; //xp用於存放x的i次方
for(i=0;i<=n;i++)
{
sum+=xp*(*p++);
xp*=x;
}
printf("Value is:%f",sum);
}//polyvalue
第二章 線性表
2.10
Status DeleteK(SqList &a,int i,int k)//刪除線性表a中第i個元素起的k個元素
{
if(i<1||k<0||i+k-1>a.length) return INFEASIBLE;
for(count=1;i+count-1<=a.length-k;count++) //注意循環結束的條件
a.elem[i+count-1]=a.elem[i+count+k-1];
a.length-=k;
return OK;
}//DeleteK
2.11
Status Insert_SqList(SqList &va,int x)//把x插入遞增有序表va中
{
if(va.length+1>va.listsize) return ERROR;
va.length++;
for(i=va.length-1;va.elem[i]>x&&i>=0;i--)
va.elem[i+1]=va.elem[i];
va.elem[i+1]=x;
return OK;
}//Insert_SqList
2.12
int ListComp(SqList A,SqList B)//比較字元表A和B,並用返回值表示結果,值為正,表示A>B;值為負,表示A<B;值為零,表示A=B
{
for(i=1;A.elem[i]||B.elem[i];i++)
if(A.elem[i]!=B.elem[i]) return A.elem[i]-B.elem[i];
return 0;
}//ListComp
2.13
LNode* Locate(LinkList L,int x)//鏈表上的元素查找,返回指針
{
for(p=l->next;p&&p->data!=x;p=p->next);
return p;
}//Locate
2.14
int Length(LinkList L)//求鏈表的長度
{
for(k=0,p=L;p->next;p=p->next,k++);
return k;
}//Length
2.15
void ListConcat(LinkList ha,LinkList hb,LinkList &hc)//把鏈表hb接在ha後面形成鏈表hc
{
hc=ha;p=ha;
while(p->next) p=p->next;
p->next=hb;
}//ListConcat
2.16
見書後答案.
2.17
Status Insert(LinkList &L,int i,int b)//在無頭結點鏈表L的第i個元素之前插入元素b
{
p=L;q=(LinkList*)malloc(sizeof(LNode));
q.data=b;
if(i==1)
{
q.next=p;L=q; //插入在鏈表頭部
}
else
{
while(--i>1) p=p->next;
q->next=p->next;p->next=q; //插入在第i個元素的位置
}
}//Insert
2.18
Status Delete(LinkList &L,int i)//在無頭結點鏈表L中刪除第i個元素
{
if(i==1) L=L->next; //刪除第一個元素
else
{
p=L;
while(--i>1) p=p->next;
p->next=p->next->next; //刪除第i個元素
}
}//Delete
2.19
Status Delete_Between(Linklist &L,int mink,int maxk)//刪除元素遞增排列的鏈表L中值大於mink且小於maxk的所有元素
{
p=L;
while(p->next->data<=mink) p=p->next; //p是最後一個不大於mink的元素
if(p->next) //如果還有比mink更大的元素
{
q=p->next;
while(q->data<maxk) q=q->next; //q是第一個不小於maxk的元素
p->next=q;
}
}//Delete_Between
2.20
Status Delete_Equal(Linklist &L)//刪除元素遞增排列的鏈表L中所有值相同的元素
{
p=L->next;q=p->next; //p,q指向相鄰兩元素
while(p->next)
{
if(p->data!=q->data)
{
p=p->next;q=p->next; //當相鄰兩元素不相等時,p,q都向後推一步
}
else
{
while(q->data==p->data)
{
free(q);
q=q->next;
}
p->next=q;p=q;q=p->next; //當相鄰元素相等時刪除多餘元素
}//else
}//while
}//Delete_Equal
2.21
void reverse(SqList &A)//順序表的就地逆置
{
for(i=1,j=A.length;i<j;i++,j--)
A.elem[i]<->A.elem[j];
}//reverse
2.22
void LinkList_reverse(Linklist &L)//鏈表的就地逆置;為簡化演算法,假設表長大於2
{
p=L->next;q=p->next;s=q->next;p->next=NULL;
while(s->next)
{
q->next=p;p=q;
q=s;s=s->next; //把L的元素逐個插入新表表頭
}
q->next=p;s->next=q;L->next=s;
}//LinkList_reverse
分析:本演算法的思想是,逐個地把L的當前元素q插入新的鏈表頭部,p為新表表頭.
2.23
void merge1(LinkList &A,LinkList &B,LinkList &C)//把鏈表A和B合並為C,A和B的元素間隔排列,且使用原存儲空間
{
p=A->next;q=B->next;C=A;
while(p&&q)
{
s=p->next;p->next=q; //將B的元素插入
if(s)
{
t=q->next;q->next=s; //如A非空,將A的元素插入
}
p=s;q=t;
}//while
}//merge1
2.24
void reverse_merge(LinkList &A,LinkList &B,LinkList &C)//把元素遞增排列的鏈表A和B合並為C,且C中元素遞減排列,使用原空間
{
pa=A->next;pb=B->next;pre=NULL; //pa和pb分別指向A,B的當前元素
while(pa||pb)
{
if(pa->data<pb->data||!pb)
{
pc=pa;q=pa->next;pa->next=pre;pa=q; //將A的元素插入新表
}
else
{
pc=pb;q=pb->next;pb->next=pre;pb=q; //將B的元素插入新表
}
pre=pc;
}
C=A;A->next=pc; //構造新表頭
}//reverse_merge
分析:本演算法的思想是,按從小到大的順序依次把A和B的元素插入新表的頭部pc處,最後處理A或B的剩餘元素.
2.25
void SqList_Intersect(SqList A,SqList B,SqList &C)//求元素遞增排列的線性表A和B的元素的交集並存入C中
{
i=1;j=1;k=0;
while(A.elem[i]&&B.elem[j])
{
if(A.elem[i]<B.elem[j]) i++;
if(A.elem[i]>B.elem[j]) j++;
if(A.elem[i]==B.elem[j])
{
C.elem[++k]=A.elem[i]; //當發現了一個在A,B中都存在的元素,
i++;j++; //就添加到C中
}
}//while
}//SqList_Intersect
2.26
void LinkList_Intersect(LinkList A,LinkList B,LinkList &C)//在鏈表結構上重做上題
{
p=A->next;q=B->next;
pc=(LNode*)malloc(sizeof(LNode));
while(p&&q)
{
if(p->data<q->data) p=p->next;
else if(p->data>q->data) q=q->next;
else
{
s=(LNode*)malloc(sizeof(LNode));
s->data=p->data;
pc->next=s;pc=s;
p=p->next;q=q->next;
}
}//while
C=pc;
}//LinkList_Intersect
2.27
void SqList_Intersect_True(SqList &A,SqList B)//求元素遞增排列的線性表A和B的元素的交集並存回A中
{
i=1;j=1;k=0;
while(A.elem[i]&&B.elem[j])
{
if(A.elem[i]<B.elem[j]) i++;
else if(A.elem[i]>B.elem[j]) j++;
else if(A.elem[i]!=A.elem[k])
{
A.elem[++k]=A.elem[i]; //當發現了一個在A,B中都存在的元素
i++;j++; //且C中沒有,就添加到C中
}
}//while
while(A.elem[k]) A.elem[k++]=0;
}//SqList_Intersect_True
2.28
void LinkList_Intersect_True(LinkList &A,LinkList B)//在鏈表結構上重做上題
{
p=A->next;q=B->next;pc=A;
while(p&&q)
{
if(p->data<q->data) p=p->next;
else if(p->data>q->data) q=q->next;
else if(p->data!=pc->data)
{
pc=pc->next;
pc->data=p->data;
p=p->next;q=q->next;
}
}//while
}//LinkList_Intersect_True
2.29
void SqList_Intersect_Delete(SqList &A,SqList B,SqList C)
{
i=0;j=0;k=0;m=0; //i指示A中元素原來的位置,m為移動後的位置
while(i<A.length&&j<B.length&& k<C.length)
{
if(B.elem[j]<C.elem[k]) j++;
else if(B.elem[j]>C.elem[k]) k++;
else
{
same=B.elem[j]; //找到了相同元素same
while(B.elem[j]==same) j++;
while(C.elem[k]==same) k++; //j,k後移到新的元素
while(i<A.length&&A.elem[i]<same)
A.elem[m++]=A.elem[i++]; //需保留的元素移動到新位置
while(i<A.length&&A.elem[i]==same) i++; //跳過相同的元素
}
}//while
while(i<A.length)
A.elem[m++]=A.elem[i++]; //A的剩餘元素重新存儲。
A.length=m;
}// SqList_Intersect_Delete
分析:先從B和C中找出共有元素,記為same,再在A中從當前位置開始, 凡小於same的
元素均保留(存到新的位置),等於same的就跳過,到大於same時就再找下一個same.
2.30
void LinkList_Intersect_Delete(LinkList &A,LinkList B,LinkList C)//在鏈表結構上重做上題
{
p=B->next;q=C->next;r=A-next;
while(p&&q&&r)
{
if(p->data<q->data) p=p->next;
else if(p->data>q->data) q=q->next;
else
{
u=p->data; //確定待刪除元素u
while(r->next->data<u) r=r->next; //確定最後一個小於u的元素指針r
if(r->next->data==u)
{
s=r->next;
while(s->data==u)
{
t=s;s=s->next;free(t); //確定第一個大於u的元素指針s
}//while
r->next=s; //刪除r和s之間的元素
}//if
while(p->data=u) p=p->next;
while(q->data=u) q=q->next;
}//else
}//while
}//LinkList_Intersect_Delete
2.31
Status Delete_Pre(CiLNode *s)//刪除單循環鏈表中結點s的直接前驅
{
p=s;
while(p->next->next!=s) p=p->next; //找到s的前驅的前驅p
p->next=s;
return OK;
}//Delete_Pre
2.32
Status DuLNode_Pre(DuLinkList &L)//完成雙向循環鏈表結點的pre域
{
for(p=L;!p->next->pre;p=p->next) p->next->pre=p;
return OK;
}//DuLNode_Pre
2.33
Status LinkList_Divide(LinkList &L,CiList &A,CiList &B,CiList &C)//把單鏈表L的元素按類型分為三個循環鏈表.CiList為帶頭結點的單循環鏈表類型.
{
s=L->next;
A=(CiList*)malloc(sizeof(CiLNode));p=A;
B=(CiList*)malloc(sizeof(CiLNode));q=B;
C=(CiList*)malloc(sizeof(CiLNode));r=C; //建立頭結點
while(s)
{
if(isalphabet(s->data))
{
p->next=s;p=s;
}
else if(isdigit(s->data))
{
q->next=s;q=s;
}
else
{
r->next=s;r=s;
}
}//while
p->next=A;q->next=B;r->next=C; //完成循環鏈表
}//LinkList_Divide
2.34
void Print_XorLinkedList(XorLinkedList L)//從左向右輸出異或鏈表的元素值
{
p=L.left;pre=NULL;
while(p)
{
printf("%d",p->data);
q=XorP(p->LRPtr,pre);
pre=p;p=q; //任何一個結點的LRPtr域值與其左結點指針進行異或運算即得到其右結點指針
}
}//Print_XorLinkedList
2.35
Status Insert_XorLinkedList(XorLinkedList &L,int x,int i)//在異或鏈表L的第i個元素前插入元素x
{
p=L.left;pre=NULL;
r=(XorNode*)malloc(sizeof(XorNode));
r->data=x;
if(i==1) //當插入點在最左邊的情況
{
p->LRPtr=XorP(p.LRPtr,r);
r->LRPtr=p;
L.left=r;
return OK;
}
j=1;q=p->LRPtr; //當插入點在中間的情況
while(++j<i&&q)
{
q=XorP(p->LRPtr,pre);
pre=p;p=q;
}//while //在p,q兩結點之間插入
if(!q) return INFEASIBLE; //i不可以超過表長
p->LRPtr=XorP(XorP(p->LRPtr,q),r);
q->LRPtr=XorP(XorP(q->LRPtr,p),r);
r->LRPtr=XorP(p,q); //修改指針
return OK;
}//Insert_XorLinkedList
2.36
Status Delete_XorLinkedList(XorlinkedList &L,int i)//刪除異或鏈表L的第i個元素
{
p=L.left;pre=NULL;
if(i==1) //刪除最左結點的情況
{
q=p->LRPtr;
q->LRPtr=XorP(q->LRPtr,p);
L.left=q;free(p);
return OK;
}
j=1;q=p->LRPtr;
while(++j<i&&q)
{
q=XorP(p->LRPtr,pre);
pre=p;p=q;
}//while //找到待刪結點q
if(!q) return INFEASIBLE; //i不可以超過表長
if(L.right==q) //q為最右結點的情況
{
p->LRPtr=XorP(p->LRPtr,q);
L.right=p;free(q);
return OK;
}
r=XorP(q->LRPtr,p); //q為中間結點的情況,此時p,r分別為其左右結點
p->LRPtr=XorP(XorP(p->LRPtr,q),r);
r->LRPtr=XorP(XorP(r->LRPtr,q),p); //修改指針
free(q);
return OK;
}//Delete_XorLinkedList
2.37
void OEReform(DuLinkedList &L)//按1,3,5,...4,2的順序重排雙向循環鏈表L中的所有結點
{
p=L.next;
while(p->next!=L&&p->next->next!=L)
{
p->next=p->next->next;
p=p->next;
} //此時p指向最後一個奇數結點
if(p->next==L) p->next=L->pre->pre;
else p->next=l->pre;
p=p->next; //此時p指向最後一個偶數結點
while(p->pre->pre!=L)
{
p->next=p->pre->pre;
p=p->next;
}
p->next=L; //按題目要求調整了next鏈的結構,此時pre鏈仍為原狀
for(p=L;p->next!=L;p=p->next) p->next->pre=p;
L->pre=p; //調整pre鏈的結構,同2.32方法
}//OEReform
分析:next鏈和pre鏈的調整隻能分開進行.如同時進行調整的話,必須使用堆棧保存偶數結點的指針,否則將會破壞鏈表結構,造成結點丟失.
2.38
DuLNode * Locate_DuList(DuLinkedList &L,int x)//帶freq域的雙向循環鏈表上的查找
{
p=L.next;
while(p.data!=x&&p!=L) p=p->next;
if(p==L) return NULL; //沒找到
p->freq++;q=p->pre;
while(q->freq<=p->freq) q=q->pre; //查找插入位置
if(q!=p->pre)
{
p->pre->next=p->next;p->next->pre=p->pre;
q->next->pre=p;p->next=q->next;
q->next=p;p->pre=q; //調整位置
}
return p;
}//Locate_DuList
2.39
float GetValue_SqPoly(SqPoly P,int x0)//求升冪順序存儲的稀疏多項式的值
{
PolyTerm *q;
xp=1;q=P.data;
sum=0;ex=0;
while(q->coef)
{
while(ex<q->exp) xp*=x0;
sum+=q->coef*xp;
q++;
}
return sum;
}//GetValue_SqPoly
2.40
void Subtract_SqPoly(SqPoly P1,SqPoly P2,SqPoly &P3)//求稀疏多項式P1減P2的差式P3
{
PolyTerm *p,*q,*r;
Create_SqPoly(P3); //建立空多項式P3
p=P1.data;q=P2.data;r=P3.data;
while(p->coef&&q->coef)
{
if(p->exp<q->exp)
{
r->coef=p->coef;
r->exp=p->exp;
p++;r++;
}
else if(p->exp<q->exp)
{
r->coef=-q->coef;
r->exp=q->exp;
q++;r++;
}
else
{
if((p->coef-q->coef)!=0) //只有同次項相減不為零時才需要存入P3中
{
r->coef=p->coef-q->coef;
r->exp=p->exp;r++;
}//if
p++;q++;
}//else
}//while
while(p->coef) //處理P1或P2的剩餘項
{
r->coef=p->coef;
r->exp=p->exp;
p++;r++;
}
while(q->coef)
{
r->coef=-q->coef;
r->exp=q->exp;
q++;r++;
}
}//Subtract_SqPoly
2.41
void QiuDao_LinkedPoly(LinkedPoly &L)//對有頭結點循環鏈表結構存儲的稀疏多項式L求導
{
p=L->next;
if(!p->data.exp)
{
L->next=p->next;p=p->next; //跳過常數項
}
while(p!=L)
{
p->data.coef*=p->data.exp--;//對每一項求導
p=p->next;
}
}//QiuDao_LinkedPoly
2.42
void Divide_LinkedPoly(LinkedPoly &L,&A,&B)//把循環鏈表存儲的稀疏多項式L拆成只含奇次項的A和只含偶次項的B
{
p=L->next;
A=(PolyNode*)malloc(sizeof(PolyNode));
B=(PolyNode*)malloc(sizeof(PolyNode));
pa=A;pb=B;
while(p!=L)
{
if(p->data.exp!=2*(p->data.exp/2))
{
pa->next=p;pa=p;
}
else
{
pb->next=p;pb=p;
}
p=p->next;
}//while
pa->next=A;pb->next=B;
}//Divide_LinkedPoly
2. 求數據結構C語言版嚴蔚敏吳偉民pdf版 紫色封面
《數據結構:C語言版》(嚴蔚敏).pdf(選擇普通下載即可!)
1、手機瀏覽器網頁端登 陸 或 PC電腦端登陸,即可查看、下載;
2、文件有時效性,若文件失效或下載問題,請留言;
3. 求數據結構C語言版嚴蔚敏(第四版)pdf 圖上這本
展開所有強烈建議購買外國版本。數據結構(c 語言版本)由霍洛維茨等人翻譯出版社: 中國機器出版社傳統的內容和組織這類教材。層次分明,代碼質量高。作者的教學經歷,可以從該書的總體敘述中看出來。雖然有一定的難度,但作者從頭到尾,都是從相關的基礎知識,一步一步來的。(例如,c 的數據存儲?),這是遠遠好於嚴偉民的。最重要的是,與嚴的教科書相比,書中的證明非常簡潔。嚴的教科書是一場噩夢(例如,嚴的關於模式匹配的書)。
4. 有沒有數據結構(C語言版)的資料
數據結構復習重點歸納筆記[清華嚴蔚敏版]
數據結構復習重點歸納[適於清華嚴版教材]
一、數據結構的章節結構及重點構成
數據結構學科的章節劃分基本上為:概論,線性表,棧和隊列,串,多維數組和廣義表,樹和二叉樹,圖,查找,內排,外排,文件,動態存儲分配。
對於絕大多數的學校而言,「外排,文件,動態存儲分配」三章基本上是不考的,在大多數高校的計算機本科教學過程中,這三章也是基本上不作講授的。所以,大家在這三章上可以不必花費過多的精力,只要知道基本的概念即可。但是,對於報考名校特別是該校又有在試卷中對這三章進行過考核的歷史,那麼這部分朋友就要留意這三章了。
按照以上我們給出的章節以及對後三章的介紹,數據結構的章節比重大致為:
概論:內容很少,概念簡單,分數大多隻有幾分,有的學校甚至不考。
線性表:基礎章節,必考內容之一。考題多數為基本概念題,名校考題中,鮮有大型演算法設計題。如果有,也是與其它章節內容相結合。
棧和隊列:基礎章節,容易出基本概念題,必考內容之一。而棧常與其它章節配合考查,也常與遞歸等概念相聯系進行考查。
串 :基礎章節,概念較為簡單。專門針對於此章的大型演算法設計題很少,較常見的是根據KMP進行演算法分析。
多維數組及廣義表
:基礎章節,基於數組的演算法題也是常見的,分數比例波動較大,是出題的「可選單元」或「侯補單元」。一般如果要出題,多數不會作為大題出。數組常與「查找,排序」等章節結合來作為大題考查。
樹和二叉樹
:重點難點章節,各校必考章節。各校在此章出題的不同之處在於,是否在本章中出一到兩道大的演算法設計題。通過對多所學校的試卷分析,絕大多數學校在本章都曾有過出大型演算法設計題的歷史。
圖 :重點難點章節,名校尤愛考。如果作為重點來考,則多出現於分析與設計題型當中,可與樹一章共同構成演算法設計大題的題型設計。
查找
:重點難點章節,概念較多,聯系較為緊密,容易混淆。出題時可以作為分析型題目給出,在基本概念型題目中也較為常見。演算法設計型題中可以數組結合來考查,也可以與樹一章結合來考查。
排序
:與查找一章類似,本章同屬於重點難點章節,且概念更多,聯系更為緊密,概念之間更容易混淆。在基本概念的考查中,尤愛考各種排序演算法的優劣比較此類的題。演算法設計大題中,如果作為出題,那麼常與數組結合來考查。
二、數據結構各章節重點勾劃:
第0章 概述
本章主要起到總領作用,為讀者進行數據結構的學習進行了一些先期鋪墊。大家主要注意以下幾點:數據結構的基本概念,時間和空間復雜度的概念及度量方法,演算法設計時的注意事項。本章考點不多,只要稍加註意理解即可。
第一章 線性表
作為線性結構的開篇章節,線性表一章在線性結構的學習乃至整個數據結構學科的學習中,其作用都是不可低估的。在這一章,第一次系統性地引入鏈式存儲的概念,鏈式存儲概念將是整個數據結構學科的重中之重,無論哪一章都涉及到了這個概念。
總體來說,線性表一章可供考查的重要考點有以下幾個方面:
1.線性表的相關基本概念,如:前驅、後繼、表長、空表、首元結點,頭結點,頭指針等概念。
2.線性表的結構特點,主要是指:除第一及最後一個元素外,每個結點都只有一個前趨和只有一個後繼。
3.線性表的順序存儲方式及其在具體語言環境下的兩種不同實現:表空間的靜態分配和動態分配。靜態鏈表與順序表的相似及不同之處。
4.線性表的鏈式存儲方式及以下幾種常用鏈表的特點和運算:單鏈表、循環鏈表,雙向鏈表,雙向循環鏈表。其中,單鏈表的歸並演算法、循環鏈表的歸並演算法、雙向鏈表及雙向循環鏈表的插入和刪除演算法等都是較為常見的考查方式。此外,近年來在不少學校中還多次出現要求用遞歸演算法實現單鏈表輸出(可能是順序也可能是倒序)的問題。
在鏈表的小題型中,經常考到一些諸如:判表空的題。在不同的鏈表中,其判表空的方式是不一樣的,請大家注意。
5.線性表的順序存儲及鏈式存儲情況下,其不同的優缺點比較,即其各自適用的場合。單鏈表中設置頭指針、循環鏈表中設置尾指針而不設置頭指針以及索引存儲結構的各自好處。
第二章 棧與隊列
棧與隊列,是很多學習DS的同學遇到第一隻攔路虎,很多人從這一章開始坐暈車,一直暈到現在。所以,理解棧與隊列,是走向DS高手的一條必由之路,。
學習此章前,你可以問一下自己是不是已經知道了以下幾點:
1.棧、隊列的定義及其相關數據結構的概念,包括:順序棧,鏈棧,共享棧,循環隊列,鏈隊等。棧與隊列存取數據(請注意包括:存和取兩部分)的特點。
2.遞歸演算法。棧與遞歸的關系,以及藉助棧將遞歸轉向於非遞歸的經典演算法:n!階乘問題,fib數列問題,hanoi問題,背包問題,二叉樹的遞歸和非遞歸遍歷問題,圖的深度遍歷與棧的關系等。其中,涉及到樹與圖的問題,多半會在樹與圖的相關章節中進行考查。
3.棧的應用:數值表達式的求解,括弧的配對等的原理,只作原理性了解,具體要求考查此為題目的演算法設計題不多。
4.循環隊列中判隊空、隊滿條件,循環隊列中入隊與出隊演算法。
如果你已經對上面的幾點了如指掌,棧與隊列一章可以不看書了。注意,我說的是可以不看書,並不是可以不作題哦。
第三章 串
經歷了棧一章的痛苦煎熬後,終於迎來了串一章的柳暗花明。
串,在概念上是比較少的一個章節,也是最容易自學的章節之一,但正如每個過來人所了解的,KMP演算法是這一章的重要關隘,突破此關隘後,走過去又是一馬平川的大好DS山河了,呵呵。
串一章需要攻破的主要堡壘有:
1.串的基本概念,串與線性表的關系(串是其元素均為字元型數據的特殊線性表),空串與空格串的區別,串相等的條件
2.串的基本操作,以及這些基本函數的使用,包括:取子串,串連接,串替換,求串長等等。運用串的基本操作去完成特定的演算法是很多學校在基本操作上的考查重點。
3.順序串與鏈串及塊鏈串的區別和聯系,實現方式。
4.KMP演算法思想。KMP中next數組以及nextval數組的求法。明確傳統模式匹配演算法的不足,明確next數組需要改進之外。其中,理解演算法是核心,會求數組是得分點。不用我多說,這一節內容是本章的重中之重。可能進行的考查方式是:求next和nextval數組值,根據求得的next或nextval數組值給出運用KMP演算法進行匹配的匹配過程。
第四章 數組與廣義表
學過程序語言的朋友,數組的概念我們已經不是第一次見到了,應該已經「一回生,二回熟」了,所以,在概念上,不會存在太大障礙。但作為考研課程來說,本章的考查重點可能與大學里的程序語言所關注的不太一樣,下面會作介紹。
廣義表的概念,是數據結構里第一次出現的。它是線性表或表元素的有限序列,構成該結構的每個子表或元素也是線性結構的,所以,這一章也歸入線性結構中。
本章的考查重點有:
1.多維數組中某數組元素的position求解。一般是給出數組元素的首元素地址和每個元素佔用的地址空間並組給出多維數組的維數,然後要求你求出該數組中的某個元素所在的位置。
2.明確按行存儲和按列存儲的區別和聯系,並能夠按照這兩種不同的存儲方式求解1中類型的題。
3.將特殊矩陣中的元素按相應的換算方式存入數組中。這些矩陣包括:對稱矩陣,三角矩陣,具有某種特點的稀疏矩陣等。熟悉稀疏矩陣的三種不同存儲方式:三元組,帶輔助行向量的二元組,十字鏈表存儲。掌握將稀疏矩陣的三元組或二元組向十字鏈表進行轉換的演算法。
4.廣義表的概念,特別應該明確表頭與表尾的定義。這一點,是理解整個廣義表一節演算法的基礎。近來,在一些學校中,出現了這樣一種題目類型:給出對某個廣義表L若干個求了若干次的取頭和取尾操作後的串值,要求求出原廣義表L。大家要留意。
5.與廣義表有關的遞歸演算法。由於廣義表的定義就是遞歸的,所以,與廣義表有關的演算法也常是遞歸形式的。比如:求表深度,復制廣義表等。這種題目,可以根據不同角度廣義表的表現形式運用兩種不同的方式解答:一是把一個廣義表看作是表頭和表尾兩部分,分別對表頭和表尾進行操作;二是把一個廣義表看作是若干個子表,分別對每個子表進行操作。
第五章 樹與二叉樹
從對線性結構的研究過度到對樹形結構的研究,是數據結構課程學習的一次躍變,此次躍變完成的好壞,將直接關繫到你到實際的考試中是否可以拿到高分,而這所有的一切,將最終影響你的專業課總分。所以,樹這一章的重要性,已經不說自明了。
總體來說,樹一章的知識點包括:
二叉樹的概念、性質和存儲結構,二叉樹遍歷的三種演算法(遞歸與非遞歸),在三種基本遍歷演算法的基礎上實現二叉樹的其它演算法,線索二叉樹的概念和線索化演算法以及線索化後的查找演算法,最優二叉樹的概念、構成和應用,樹的概念和存儲形式,樹與森林的遍歷演算法及其與二叉樹遍歷演算法的聯系,樹與森林和二叉樹的轉換。
下面我們來看考試中對以上知識的主要考查方法:
1.二叉樹的概念、性質和存儲結構
考查方法可有:直接考查二叉樹的定義,讓你說明二叉樹與普通雙分支樹的區別;考查滿二叉樹和完全二叉樹的性質,普通二叉樹的五個性質:第i層的最多結點數,深度為k的二叉樹的最多結點數,n0=n2+1的性質,n個結點的完全二叉樹的深度,順序存儲二叉樹時孩子結點與父結點之間的換算關系(左為:2*i,右為:2*i+1)。
二叉樹的順序存儲和二叉鏈表存儲的各自優缺點及適用場合,二叉樹的三叉鏈表表示方法。
2.二叉樹的三種遍歷演算法
這一知識點掌握的好壞,將直接關繫到樹一章的演算法能否理解,進而關繫到樹一章的演算法設計題能否順利完成。二叉樹的遍歷演算法有三種:先序,中序和後序。其劃分的依據是視其每個演算法中對根結點數據的訪問順序而定。不僅要熟練掌握三種遍歷的遞歸演算法,理解其執行的實際步驟,並且應該熟練掌握三種遍歷的非遞歸演算法。由於二叉樹一章的很多演算法,可以直接根據三種遞歸演算法改造而來(比如:求葉子個數),所以,掌握了三種遍歷的非遞歸演算法後,對付諸如:「利用非遞歸演算法求二叉樹葉子個數」這樣的題目就下筆如有神了。我會在另一篇系列文章(http://bbs.kaoyan.com/ibbs.dll?bbsdisp?t_id=301583&bp=2&bt=0)里給出三種遍歷的遞歸和非遞歸演算法的背記版,到時請大家一定熟記。
3.可在三種遍歷演算法的基礎上改造完成的其它二叉樹演算法:
求葉子個數,求二叉樹結點總數,求度為1或度為2的結點總數,復制二叉樹,建立二叉樹,交換左右子樹,查找值為n的某個指定結點,刪除值為n的某個指定結點,諸如此類等等等等。如果你可以熟練掌握二叉樹的遞歸和非遞歸遍歷演算法,那麼解決以上問題就是小菜一碟了。
4.線索二叉樹:
線索二叉樹的引出,是為避免如二叉樹遍歷時的遞歸求解。眾所周知,遞歸雖然形式上比較好理解,但是消耗了大量的內存資源,如果遞歸層次一多,勢必帶來資源耗盡的危險,為了避免此類情況,線索二叉樹便堂而皇之地出現了。對於線索二叉樹,應該掌握:線索化的實質,三種線索化的演算法,線索化後二叉樹的遍歷演算法,基本線索二叉樹的其它演算法問題(如:查找某一類線索二叉樹中指定結點的前驅或後繼結點就是一類常考題)。
5.最優二叉樹(哈夫曼樹):
最優二叉樹是為了解決特定問題引出的特殊二叉樹結構,它的前提是給二叉樹的每條邊賦予了權值,這樣形成的二叉樹按權相加之和是最小的。最優二叉樹一節,直接考查演算法源碼的很少,一般是給你一組數據,要求你建立基於這組數據的最優二叉樹,並求出其最小權值之和,此類題目不難,屬送分題。
6.樹與森林:
二叉樹是一種特殊的樹,這種特殊不僅僅在於其分支最多為2以及其它特徵,一個最重要的特殊之處是在於:二叉樹是有序的!即:二叉樹的左右孩子是不可交換的,如果交換了就成了另外一棵二叉樹,這樣交換之後的二叉樹與原二叉樹我們認為是不相同的兩棵二叉樹。但是,對於普通的雙分支樹而言,不具有這種性質。
樹與森林的遍歷,不像二叉樹那樣豐富,他們只有兩種遍歷演算法:先根與後根(對於森林而言稱作:先序與後序遍歷)。在難度比較大的考試中,也有基於此二種演算法的基礎上再進行擴展要求你利用這兩種演算法設計其它演算法的,但一般院校很少有這種考法,最多隻是要求你根據先根或後根寫出他們的遍歷序列。此二者的先根與後根遍歷與二叉樹中的遍歷演算法是有對應關系的:先根遍歷對應二叉樹的先序遍歷,而後根遍歷對應二叉樹的中序遍歷。這一點成為很多學校的考點,考查的方式不一而足,有的直接考此句話,有的是先讓你求解遍歷序列然後回答這個問題。二叉樹、樹與森林之所以能有以上的對應關系,全拜二叉鏈表所賜。二叉樹使用二叉鏈表分別存放他的左右孩子,樹利用二叉鏈表存儲孩子及兄弟(稱孩子兄弟鏈表),而森林也是利用二叉鏈表存儲孩子及兄弟。
樹一章,處處是重點,道道是考題,大家務必個個過關。
第六章 圖
如果說,從線性結構向樹形結構研究的轉變,是數據結構學科對數據組織形式研究的一次升華,那麼從樹形結構的研究轉到圖形結構的研究,則進一步讓我們看到了數據結構對於解決實際問題的重大推動作用。
圖這一章的特點是:概念繁多,與離散數學中圖的概念聯系緊密,演算法復雜,極易被考到,且容易出大題,尤其是名校,作為考研課程,如果不考查樹與圖兩章的知識,幾乎是不可想像的。
下面我們看一下圖這一章的主要考點以及這些考點的考查方式:
1.考查有關圖的基本概念問題:
這些概念是進行圖一章學習的基礎,這一章的概念包括:圖的定義和特點,無向圖,有向圖,入度,出度,完全圖,生成子圖,路徑長度,迴路,(強)連通圖,(強)連通分量等概念。與這些概念相聯系的相關計算題也應該掌握。
2.考查圖的幾種存儲形式:
圖的存儲形式包括:鄰接矩陣,(逆)鄰接表,十字鏈表及鄰接多重表。在考查時,有的學校是給出一種存儲形式,要求考生用演算法或手寫出與給定的結構相對應的該圖的另一種存儲形式。
3.考查圖的兩種遍歷演算法:深度遍歷和廣度遍歷
深度遍歷和廣度遍歷是圖的兩種基本的遍歷演算法,這兩個演算法對圖一章的重要性等同於「先序、中序、後序遍歷」對於二叉樹一章的重要性。在考查時,圖一章的演算法設計題常常是基於這兩種基本的遍歷演算法而設計的,比如:「求最長的最短路徑問題」和「判斷兩頂點間是否存在長為K的簡單路徑問題」,就分別用到了廣度遍歷和深度遍歷演算法。
4.生成樹、最小生成樹的概念以及最小生成樹的構造:PRIM演算法和KRUSKAL演算法。
考查時,一般不要求寫出演算法源碼,而是要求根據這兩種最小生成樹的演算法思想寫出其構造過程及最終生成的最小生成樹。
5.拓撲排序問題:
拓撲排序有兩種方法,一是無前趨的頂點優先演算法,二是無後繼的頂點優先演算法。換句話說,一種是「從前向後」的排序,一種是「從後向前」排。當然,後一種排序出來的結果是「逆拓撲有序」的。
6.關鍵路徑問題:
這個問題是圖一章的難點問題。理解關鍵路徑的關鍵有三個方面:一是何謂關鍵路徑,二是最早時間是什麼意思、如何求,三是最晚時間是什麼意思、如何求。簡單地說,最早時間是通過「從前向後」的方法求的,而最晚時間是通過「從後向前」的方法求解的,並且,要想求最晚時間必須是在所有的最早時間都已經求出來之後才能進行。這個問題拿來直接考演算法源碼的不多,一般是要求按照書上的演算法描述求解的過程和步驟。
在實際設計關鍵路徑的演算法時,還應該注意以下這一點:採用鄰接表的存儲結構,求最早時間和最晚時間要採用不同的處理方法,即:在演算法初始時,應該首先將所有頂點的最早時間全部置為0。關鍵路徑問題是工程進度控制的重要方法,具有很強的實用性。
7.最短路徑問題:
與關鍵路徑問題並稱為圖一章的兩只攔路虎。概念理解是比較容易的,關鍵是演算法的理解。最短路徑問題分為兩種:一是求從某一點出發到其餘各點的最短路徑;二是求圖中每一對頂點之間的最短路徑。這個問題也具有非常實用的背景特色,一個典型的應該就是旅遊景點及旅遊路線的選擇問題。解決第一個問題用DIJSKTRA演算法,解決第二個問題用FLOYD演算法。注意區分。
第七章 查找
在不少數據結構的教材中,是把查找與排序放入高級數據結構中的。應該說,查找和排序兩章是前面我們所學的知識的綜合運用,用到了樹、也用到了鏈表等知識,對這些數據結構某一方面的運用就構成了查找和排序。
現實生活中,search幾乎無處不在,特別是現在的網路時代,萬事離不開search,小到文檔內文字的搜索,大到INTERNET上的搜索,search占據了我們上網的大部分時間。
在復習這一章的知識時,你需要先弄清楚以下幾個概念:
關鍵字、主關鍵字、次關鍵字的含義;靜態查找與動態查找的含義及區別;平均查找長度ASL的概念及在各種查找演算法中的計算方法和計算結果,特別是一些典型結構的ASL值,應該記住。
在DS的教材中,一般將search分為三類:1st,在順序表上的查找;2nd,在樹表上的查找;3rd,在哈希表上的查找。下面詳細介紹其考查知識點及考查方式:
1.線性表上的查找:
主要分為三種線性結構:順序表,有序順序表,索引順序表。對於第一種,我們採用傳統查找方法,逐個比較。對於及有序順序表我們採用二分查找法。對於第三種索引結構,我們採用索引查找演算法。考生需要注意這三種表下的ASL值以及三種演算法的實現。其中,二分查找還要特別注意適用條件以及其遞歸實現方法。
2.樹表上的查找:
這是本章的重點和難點。由於這一節介紹的內容是使用樹表進行的查找,所以很容易與樹一間的某些概念相混淆。本節內容與樹一章的內容有聯系,但也有很多不同,應注意規納。樹表主要分為以下幾種:二叉排序樹,平衡二叉樹,B樹,鍵樹。其中,尤以前兩種結構為重,也有部分名校偏愛考B樹的。由於二叉排序樹與平衡二叉樹是一種特殊的二叉樹,所以與二叉樹的聯系就更為緊密,二叉樹一章學好了,這里也就不難了。
二叉排序樹,簡言之,就是「左小右大」,它的中序遍歷結果是一個遞增的有序序列。平衡二叉樹是二叉排序樹的優化,其本質也是一種二叉排序樹,只不過,平衡二叉樹對左右子樹的深度有了限定:深度之差的絕對值不得大於1。對於二叉排序樹,「判斷某棵二叉樹是否二叉排序樹」這一演算法經常被考到,可用遞歸,也可以用非遞歸。平衡二叉樹的建立也是一個常考點,但該知識點歸根結底還是關注的平衡二叉樹的四種調整演算法,所以應該掌握平衡二叉樹的四種調整演算法,調整的一個參照是:調整前後的中序遍歷結果相同。
B樹是二叉排序樹的進一步改進,也可以把B樹理解為三叉、四叉....排序樹。除B樹的查找演算法外,應該特別注意一下B樹的插入和刪除演算法。因為這兩種演算法涉及到B樹結點的分裂和合並,是一個難點。B樹是報考名校的同學應該關注的焦點之一。
鍵樹也稱字元樹,特別適用於查找英文單詞的場合。一般不要求能完整描述演算法源碼,多是根據演算法思想建立鍵樹及描述其大致查找過程。
3.基本哈希表的查找演算法:
哈希一詞,是外來詞,譯自「hash」一詞,意為:散列或雜湊的意思。哈希表查找的基本思想是:根據當前待查找數據的特徵,以記錄關鍵字為自變數,設計一個function,該函數對關鍵字進行轉換後,其解釋結果為待查的地址。基於哈希表的考查點有:哈希函數的設計,沖突解決方法的選擇及沖突處理過程的描述。
第八章 內部排序
內排是DS課程中最後一個重要的章節,建立在此章之上的考題可以有多種類型:填空,選擇,判斷乃至大型演算法題。但是,歸結到一點,就是考查你對書本上的各種排序演算法及其思想以及其優缺點和性能指標(時間復雜度)能否了如指掌。
這一章,我們對重點的規納將跟以上各章不同。我們將從以下幾個側面來對排序一章進行不同的規納,以期能更全面的理解排序一章的總體結構及各種演算法。
從排序演算法的種類來分,本章主要闡述了以下幾種排序方法:插入、選擇、交換、歸並、計數等五種排序方法。
其中,在插入排序中又可分為:直接插入、折半插入、2路插入、希爾排序。這幾種插入排序演算法的最根本的不同點,說到底就是根據什麼規則尋找新元素的插入點。直接插入是依次尋找,折半插入是折半尋找。希爾排序,是通過控制每次參與排序的數的總范圍「由小到大」的增量來實現排序效率提高的目的。
交換排序,又稱冒泡排序,在交換排序的基礎上改進又可以得到快速排序。快速排序的思想,一語以敝之:用中間數將待排數據組一分為二。快速排序,在處理的「問題規模」這個概念上,與希爾有點相反,快速排序,是先處理一個較大規模,然後逐漸把處理的規模降低,最終達到排序的目的。
選擇排序,相對於前面幾種排序演算法來說,難度大一點。具體來說,它可以分為:簡單選擇、樹選擇、堆排。這三種方法的不同點是,根據什麼規則選取最小的數。簡單選擇,是通過簡單的數組遍歷方案確定最小數;樹選擇,是通過「錦標賽」類似的思想,讓兩數相比,不斷淘汰較大(小)者,最終選出最小(大)數;而堆排序,是利用堆這種數據結構的性質,通過堆元素的刪除、調整等一系列操作將最小數選出放在堆頂。堆排序中的堆建立、堆調整是重要考點。樹選擇排序,也曾經在一些學校中的大型演算法題中出現,請大家注意。
歸並排序,故名思義,是通過「歸並」這種操作完成排序的目的,既然是歸並就必須是兩者以上的數據集合才可能實現歸並。所以,在歸並排序中,關注最多的就是2路歸並。演算法思想比較簡單,有一點,要銘記在心:歸並排序是穩定排序。
基數排序,是一種很特別的排序方法,也正是由於它的特殊,所以,基數排序就比較適合於一些特別的場合,比如撲克牌排序問題等。基數排序,又分為兩種:多關鍵字的排序(撲克牌排序),鏈式排序(整數排序)。基數排序的核心思想也是利用「基數空間」這個概念將問題規模規范、變小,並且,在排序的過程中,只要按照基排的思想,是不用進行關鍵字比較的,這樣得出的最終序列就是一個有序序列。
本章各種排序演算法的思想以及偽代碼實現,及其時間復雜度都是必須掌握的,學習時要多注意規納、總結、對比。此外,對於教材中的10.7節,要求必須熟記,在理解的基礎上記憶,這一節幾乎成為很多學校每年的必考點。
至此,數據結構所有章節的章節重點問題,我們已經規納完畢,使用清華嚴版教材的同學,在復習的同時,可以參照本貼給出的重點進行復習。但是,由於作者本人水平有限,可能有很多考點沒有規納出來,也可能有些考點規納有誤,在此,作者本人誠懇希望諸位朋友直面提出,我會不斷完善和發布新的關於數據結構復習的總結以及筆記
嚴蔚敏數據結構為主的筆記二
第二章:線性表(包括習題與答案及要點)
--------------------------------------------------------------------------------
本章的重點是掌握順序表和單鏈表上實現的各種基本演算法及相關的時間性能分析,難點是使用本章所學的基本知識設計有效演算法解決與線性表相關的應用問題。
要求達到<識記>層次的內容有:線性表的邏輯結構特徵;線性表上定義的基本運算,並利用基本運算構造出較復雜的運算。
要求達到<綜合應用>層次的內容有:順序表的含義及特點,順序表上的插入、刪除操作及其平均時間性能分析,解決簡單應用問題。
鏈表如何表示線性表中元素之間的邏輯關系;單鏈表、雙鏈表、循環鏈表鏈接方式上的區別;單鏈表上實現的建表、查找、插入和刪除等基本演算法及其時間復雜度。循環鏈表上尾指針取代頭指針的作用,以及單循環鏈表上的演算法與單鏈表上相應演算法的異同點。雙鏈表的定義和相關演算法。利用鏈表設計演算法解決簡單應用問題。
要求達到<領會>層次的內容就是順序表和鏈表的比較,以及如何選擇其一作為其存儲結構才能取得較優的時空性能。
--------------------------------------------------------------------------------
線性表的邏輯結構特徵是很容易理解的,如其名,它的邏輯結構特徵就好象是一條線,上面打了一個個結,很形象的,如果這條線上面有結,那麼它就是非空表,只能有一個開始結點,有且只能有一個終端結點,其它的結前後所相鄰的也只能是一個結點(直接前趨和直接後繼)。
關於線性表上定義的基本運算,主要有構造空表、求表長、取結點、查找、插入、刪除等。
--------------------------------------------------------------------------------
線性表的邏輯結構和存儲結構之間的關系。在計算機中,如何把線性表的結點存放到存儲單元中,就有許多方法,最簡單的方法就是按順序存儲。就是按線性表的邏輯結構次序依次存放在一組地址連續的存儲單元中。在存儲單元中的各元素的物理位置和邏輯結構中各結點相鄰關系是一致的。
在順序表中實現的基本運算主要討論了插入和刪除兩種運算。相關的演算法我們通過練習掌握。對於順序表的插入和刪除運算,其平均時間復雜度均為O(n)。
--------------------------------------------------------------------------------
線性表的鏈式存儲結構。它與順序表不同,鏈表是用一組任意的存儲單元來存放線性表的結點,這組存儲單元可以分布在內存中任何位置上。因此,鏈表中結點的邏輯次序和物理次序不一定相同。所以為了能正確表示結點間的邏輯關系,在存儲每個結點值的同時,還存儲了其後繼結點的地址信息(即
5. 誰有《數據結構》(C語言版)嚴蔚敏,清華大學2005年的課本麻煩把目錄告知,非常感謝
數據結構(C語言版)嚴蔚敏 清華大學出版社
目錄
第1章 緒論
1.1 什麼是數據結構
1.2 基本概念和術語
1.3 抽象數據類型的表現與實現
1.4 演算法和演算法分析
第2章 線性表
2.1 線性表的類型定義
2.2 線性表的順序表示和實現
2.3 線性表的鏈式表示和實現
2.4 一元多項式的表示及相加
第3章 棧和隊列
3.1 棧
3.2 棧的應有和舉例
3.3 棧與遞歸的實現
3.4 隊列
3.5 離散事件模擬
第4章 串
4.1 串類型的定義
4.2 串的表示和實現
4.3 串的模式匹配演算法
4.4 串操作應用舉例
第5章 數組和廣義表
5.1 數組的定義
5.2 數組的順序表現和實現
5.3 矩陣的壓縮存儲
5.4 廣義表的定義
5.5 廣義表的儲存結構
5.6 m元多項式的表示
5.7 廣義表的遞歸演算法第6章 樹和二叉樹
6.1 樹的定義和基本術語
6.2 二叉樹
6.2.1 二叉樹的定義
6.2.2 二叉樹的性質
6.2.3 二叉樹的存儲結構
6.3 遍歷二叉樹和線索二叉樹
6.3.1 遍歷二叉樹
6.3.2 線索二叉樹
6.4 樹和森林
6.4.1 樹的存儲結構
6.4.2 森林與二叉樹的轉換
6.4.3 樹和森林的遍歷
6.5 樹與等價問題
6.6 赫夫曼樹及其應用
6.6.1 最優二叉樹(赫夫曼樹)
6.6.2 赫夫曼編碼
6.7 回溯法與樹的遍歷
6.8 樹的計數
第7章 圖
7.1 圖的定義和術語
7.2 圖的存儲結構
7.2.1 數組表示法
7.2.2 鄰接表
7.2.3 十字鏈表
7.2.4 鄰接多重表
7.3 圖的遍歷
7.3.1 深度優先搜索
7.3.2 廣度優先搜索
7.4 圖的連通性問題
7.4.1 無向圖的連通分量和生成樹
7.4.2 有向圖的強連通分量
7.4.3 最小生成樹
7.4.4 關節點和重連通分量
7.5 有向無環圖及其應用
7.5.1 拓撲排序
7.5.2 關鍵路徑
7.6 最短路徑
7.6.1 從某個源點到其餘各頂點的最短路徑
7.6.2 每一對頂點之間的最短路徑
第8章 動態存儲管理
8.1 概述
8.2 可利用空間表及分配方法
8.3 邊界標識法
8.3.1 可利用空間表的結構
8.3.2 分配演算法
8.3.3 回收演算法
8.4 夥伴系統
8.4.1 可利用空間表的結構
8.4.2 分配演算法
8.4.3 回收演算法
8.5 無用單元收集
8.6 存儲緊縮
第9章 查找
9.1 靜態查找表
9.1.1 順序表的查找
9.1.2 有序表的查找
9.1.3 靜態樹表的查找
9.1.4 索引順序表的查找
9.2 動態查找表
9.2.1 二叉排序樹和平衡二叉樹
9.2.2 B樹和B+樹
9.2.3 鍵樹
9.3 哈希表
9.3.1 什麼是哈希表
9.3.2 哈希函數的構造方法
9.3.3 處理沖突的方法
9.3.4 哈希表的查找及其分析
第10章 內部排序
10.1 概述
10.2 插入排序
10.2.1 直接插入排序
10.2.2 其他插入排序
10.2.3 希爾排序
10.3 快速排序
10.4 選擇排序
10.4.1 簡單選擇排序
10.4.2 樹形選擇排序
10.4.3 堆排序
10.5 歸並排序
10.6 基數排序
10.6.1 多關鍵字的排序
10.6.2 鏈式基數排序
10.7 各種內部排序方法的比較討論
第11章 外部排序
11.1 外存信息的存取
11.2 外部排序的方法
11.3 多路平衡歸並的實現
11.4 置換一選擇排序
11.5 最佳歸並樹
第12章 文件
12.1 有關文件的基本概念
12.2 順序文件
12.3 索引文件
12.4 ISAM文件和VSAM文件
12.4.1 ISAM文件
12.4.2 VSAM文件
12.5 直接存取文件(散列文件)
12.6 多關鍵字文件
12.6.1 多重表文件
12.6.2 倒排文件
附錄A 名詞索引
附錄B 函數索引
參考書目
6. 求數據結構(c語言版) 嚴蔚敏 pdf
《數據結構:C語言版》(嚴蔚敏).pdf(選擇普通下載即可)
下載下來,雙擊解壓就可以看到,資源收集於互聯網,僅供個人試讀和學習,有能力多支持正版!另郵箱發了同樣一份