數(shù)據(jù)結(jié)構(gòu)C語言版-線性表的單鏈表存儲結(jié)構(gòu)表示和實現(xiàn)_第1頁
數(shù)據(jù)結(jié)構(gòu)C語言版-線性表的單鏈表存儲結(jié)構(gòu)表示和實現(xiàn)_第2頁
數(shù)據(jù)結(jié)構(gòu)C語言版-線性表的單鏈表存儲結(jié)構(gòu)表示和實現(xiàn)_第3頁
數(shù)據(jù)結(jié)構(gòu)C語言版-線性表的單鏈表存儲結(jié)構(gòu)表示和實現(xiàn)_第4頁
數(shù)據(jù)結(jié)構(gòu)C語言版-線性表的單鏈表存儲結(jié)構(gòu)表示和實現(xiàn)_第5頁
已閱讀5頁,還剩13頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

#include<stdio.h>

#include<mallocoh>

#include(stdlib.h>

/*

數(shù)據(jù)結(jié)構(gòu)C語言版線性表的單鏈表存儲結(jié)構(gòu)表示和實現(xiàn)

P28—31

編譯環(huán)境:Dev-C++4o9o9o2

日期:2011年2月10日

*/

typedefintElemType;

//線性表的單鏈表存儲結(jié)構(gòu)

typedefstructLNode

(

ElemTypedata;〃數(shù)據(jù)域

structLNode*next;〃指針域

}LNode,*LinkList;

//typedefstructLNode*LinkList;//另一種定義LinkList的方法

//構(gòu)造一個空的線性表L

intInitList(LinkList*L)

(

/*

產(chǎn)生頭結(jié)點L,并使L指向此頭結(jié)點,頭節(jié)點的數(shù)據(jù)域為空,不放數(shù)據(jù)的。

void*malloc(size_t)

這里對返回值進行強制類型轉(zhuǎn)換了,返回值是指向空類型的指針類型.

*/

(*L)=(LinkList)malloc(sizeof(structLNode));

if(!(*L))

exit(0);//存儲分配失敗

(*L)->next=NULL;//指針域為空

return1;

)

//銷毀線性表L,將包括頭結(jié)點在內(nèi)的所有元素釋放其存儲空間。

intDestroyList(LinkList*L)

(

LinkListq;

//由于單鏈表的每一個元素是單獨分配的,所以要一個一個的進行釋放

while(*L)

(

q=(*L)—〉next;

free(夫L);〃釋放

*L=q;

return1;

}

將L重置為空表,即將鏈表中除頭結(jié)點外的所有元素釋放其存

儲空間,但是將頭結(jié)點指針域置空,這和銷毀有區(qū)別哦。不改變L,所以

不需要用指針。

*/

intClearList(LinkListL)

(

LinkListp,q;

p=L—>next;〃p指向第一個結(jié)點

while(p)//沒到表尾則繼續(xù)循環(huán)

(

q=p->next;

free(p);〃釋放空間

P二q;

)

L—>next=NULL;//頭結(jié)點指針域為空,鏈表成了一個空表

return1;

)

//若L為空表(根據(jù)頭結(jié)點L-〉next來判斷,為空則是空表),則返回1,

//否則返回0.

intListEmpty(LinkListL)

(

if(L—>next)〃非空

return0;

else

return1;

)

//返回L中數(shù)據(jù)元素個數(shù)。

intListLength(LinkListL)

(

inti=0;

LinkListp=L一〉next;〃p指向第一個結(jié)點

while(p)//沒到表尾,則繼續(xù)循環(huán)

(

i++;

p=p->next;

)

returni;

)

//算法2o8P29

〃L為帶頭結(jié)點的單鏈表的頭指針。當(dāng)?shù)趇個元素存在時,其值賦給e并

//返回1,否則返回0o

intGetElem(LinkListL,inti,ElemType*e)

intj=1;〃j為計數(shù)器

LinkListp=L一〉next;//p指向第一個結(jié)點

while(p&&j<i)//順指針向后查找,直到p指向第i個元素或p為空

{

p=p—>next;

j++;

)

if(!plIj)i)//第i個元素不存在

return0;

*e=p—)data;//取第i個元素

return1;

}

//返回L中第1個與e滿足關(guān)系compare()的數(shù)據(jù)元素的位序。

//若這樣的數(shù)據(jù)元素不存在,則返回值為0

intLocateElem(LinkListL,ElemTypee,int(compare)(ElemType,ElemType))

(

inti=0;

LinkListp=L——>next;

while(p)〃將鏈表的每一個元素進行對比

(

i++;

if(compare(p一〉data,e))//找到這樣的數(shù)據(jù)元素

returni;

p=p->next;

)

return0;

)

//若cuje是L的數(shù)據(jù)元素,且不是第一個,則用pre_e返回它的前驅(qū),

〃返回1;否則操作失敗,pre_e無定義,返回

intPriorElem(LinkListL,ElemTypecur_e,ElemType*pre_e)

(

LinkListq,

p=L—)next;〃p指向第一個結(jié)點

while(p->next)〃p所指結(jié)點有后繼

(

q=p—〉next;〃q為p的后繼

if(q->data==cur_e)

(

*pre_e=p—>data;

return1;

}

p=q;//p向后移

)

return-1;

)

〃若cur_e是L的數(shù)據(jù)元素,且不是最后一個,則用next_e返回它的后繼,

〃返回1;否則操作失敗,next_e無定義,返回-1

intNextElem(LinkListL,ElemTypecur_e,ElemType*next_e)

(

LinkListp=L一〉next;//p指向第一個結(jié)點

while(p->next)〃p所指結(jié)點有后繼

(

if(p—>data==cur_e)

{

*next_e=p-〉next-)data;

return1;

)

p=p->next;

)

return—1;

)

//算法2.9P30

//在帶頭結(jié)點的單鏈線性表L中第i個位置之前插入元素e

intListInsert(LinkLisl*L,inii,ElemTypee)

(

intj=0;

LinkListp=*L,s;

while(p&&j<i-l)//尋找第i—l個結(jié)點

(

p=p->next;

j++;

}

if(!p||j)i-D〃i小于1或者大于表長

return0;

s=(LinkList)malloc(sizeof(structLNode));//生成新結(jié)點

s->data=e;//插入L中

s—>next=p->next;

p-〉next=s;

return1;

)

//算法2。10P30

//在帶頭結(jié)點的單鏈線性表L中,刪除第i個元素,并由e返回其值

intListDelete(LinkListinti,ElemType*e)

(

intj=O;

LinkListp=*L,q;

while(p-)next&&j<i-l)//尋找第i個結(jié)點,并令p指向其前趨

p=p-)next;

j++;

)

if(!p一〉next|Ij>i-1)//刪除位置不合理

return0;

q=p—〉next;//刪除并釋放結(jié)點

p—〉next=q->next;

*e=q—〉data;

free(q);

return1;

)

//依次對L的每個數(shù)據(jù)元素調(diào)用函數(shù)vi()

intListTraverse(LinkListL,void(*vi)(ElemType))

(

LinkListp=L->next;

〃對所有元素調(diào)用函數(shù)vi

while(p)

(

vi(p—〉data);

p=p->next;

)

printf

return1:

}

//在按非降序排列的線性表L中按非降序插入新的數(shù)據(jù)元素e

voidInsertAscend(LinkListL,ElemTypee)

(

LinkListq=L,

p=L—〉next;

while(p&&e>p—〉data)

(

q=p;

p=p-)next;

)

q->next=(LinkList)malloc(sizeof(structLNode));//eqJo

q—〉next—〉data=e;

q->next—〉next=p;

)

//按非升序排列的線性表L中按非升序插入新的數(shù)據(jù)元素e

voidInsertDescend(LinkListL,ElemTypee)

(

LinkListq=L,p=L-〉next;

while(p&&e<p—>data)

q二p;

p=p-〉next;

)

q一〉next=(LinkList)malloc(sizeof(structLNode));//e插在q后

q一〉next—>data=e;

q—>next->next=p;

)

//L的頭部插入新的數(shù)據(jù)元素e,作為鏈表的第一個元素

intHeadInsert(LinkListL,ElemTypee)

(

LinkLists;

s=(LinkList)malloc(sizeof(structLNode));//生成新結(jié)點

s—>data=e;//給結(jié)點賦值

s-)next=L一>next;//插在表頭

L-)next=s;

return1;

)

〃在L的尾部插入新的數(shù)據(jù)元素e,作為鏈表的最后一個元素

intEndInsert(LinkListL,ElemTypee)

(

LinkListp=L;

while(p->next)〃使p指向表尾元素

p=p—〉next;

p一〉next=(LinkList)malloc(sizeof(structLNode));//在表尾生成新結(jié)點

p—>next—〉data=e;//給新結(jié)點賦值

p一〉next-)next=NULL;//表尾

return1;

}

〃刪除L的第一個數(shù)據(jù)元素,并由e返回其值

intDeleteFirst(LinkListL,ElemType*e)

(

LinkListp=L—〉next;

if(p)

{

*e=p—>data;

L->next=p-〉next;

free(p);

return1;

)

else

return0;

}

〃刪除L的最后一個數(shù)據(jù)元素,并用e返回其值

intDeleteTail(LinkListL,ElemType*e)

LinkListp=L,q;

if(!p—>next)//鏈表為空

return0;

while(p—〉next)

(

q=p;

p=p—>next;

)

q—〉next=NULL;//新尾結(jié)點的next域設(shè)為NULL

*e=p—〉data;

free(p);

return1;

}

//刪除表中值為e的元素,并返回1;如無此元素,則返回0

intDeleteElem(LinkListL,ElemTypee)

(

LinkListp=L,q;

while(p)

(

q=p-〉next;

if(q&&q—〉data==e)

{

p-)next=q—>next;

free(q);

return1;

)

p=q;

)

return0;

)

//用e取代表L中第i個元素的值

intReplaceElem(LinkListL,inti,ElemTypee)

(

LinkListp=L;

intj=0;

〃找到第i個元素的位置給p

while(p-)next&&j<i)

(

j++;

p=p-〉next;

)

if(j==i)

p—〉data=e;

return1;

)

else//表中不存在第i個元素

return0;

)

//按非降序建立n個元素的線性表

intCreatAscend(LinkList*L,intn)

(

intj;

LinkListp,q,s;

if(n(=0)

return0;

InitList(L);

printf("請輸入%d個元素:(空格)\n",n);

s=(LinkList)malloc(sizeof(structLNode));//第一個結(jié)點

scanf("%d”,&s—>data);

s—〉next=NULL;

(*L)—〉next=s;

for(j=l;j<n;j++)

(

s=(LinkList)malloc(sizeof(structLNode));//其余結(jié)點

scanf(''%cT,&s—〉data);

q=*L;

p=(*L)—〉next;

while(p&&p-)data<s~~>data)〃p沒到表尾,且所指元素值小于新值

(

q二p;

p=p—〉next;//指針后移

}

s->next=q—)next;//元素插在q的后面

q—〉next=s;

)

return1;

)

//按非升序建立n個元素的線性表

intCreatDescend(LinkList*L,intn)

(

intj;

LinkListp,q,s;

if(n<=0)

return0;

InitList(L);

printf("請輸入%d個元素:(空格)\n",n);

s=(LinkList)malloc(sizeof(structLNode));//第一個結(jié)點

scanf("%d”,&s-〉data);

s—〉next=NULL;

(*L)一>next=s;

for(j=l;j<n;j++)

(

s=(LinkList)malloc(sizeof(structLNode));//其余結(jié)點

scanf("%d”,&s-〉data);

q=*L;

p=(*L)—〉next;

while(p&&p—〉data)s—>data)〃p沒到表尾,且所指元素值大于新值

(

q=p;

p=p->next;//指針后移

)

s-〉next=q一〉next;//元素插在q的后面

q->next=s;

}

return1;

)

//返回表頭元素的值

intGetFirstElem(LinkListL,ElemType*e)

(

LinkListp=L->next;〃第一個結(jié)點給p

if(!p)〃空表

return0;

else//非空表

*e=p-〉data;

return1;

)

//算法2.11P30

//逆位序(插在表頭)輸入n個元素的值,建立帶表頭結(jié)構(gòu)的單鏈線性表L

voidCreateList(LinkList*L,intn)

(

inti;

LinkListp;

//先建立一個帶頭結(jié)點的空單鏈表,相當(dāng)于初始化單鏈表

*L=(LinkList)malloc(sizeof(structLNode));

(*L)—〉next=NULL;

printf("請輸入%d個數(shù)據(jù)\n",n);

for(i=n;i>0;------i)

(

p=(LinkList)malloc(sizeof(structLNode));//生成新結(jié)點

scanf("%d,\&p一〉data);//輸入元素值

p—>next=(*L)—>next;//插入到表頭

(*L)->next=p;

)

)

//正位序(插在表尾)輸入n個元素的值,建立帶表頭結(jié)構(gòu)的單鏈線性表

voidCreateList2(LinkList*L,intn)

(

inti;

LinkListp,q;

//先建立一個帶頭結(jié)點的空單鏈表,相當(dāng)于初始化單鏈表

*L=(LinkList)malloc(sizeof(structLNode));//生成頭結(jié)點

(*L)—>next=NULL;

q=*L;

printf("請輸入%d個數(shù)據(jù)\n",n);

for(i=l;i<=n;i++)

(

p=(LinkList)malloc(sizeof(structLNode));

scanf("%d”,&p—〉data);

q—>next=p;

q=q—〉next;

)

p—〉next=NULL;

)

/*

用單鏈表重寫算法2。2供參考

已知線性表La和Lb中的數(shù)據(jù)元素按值非遞減排列.

歸并La和Lb得到新的線性表Lc,Lc的數(shù)據(jù)元素也按值非遞減排列

voidMergeList(LinkListLa,LinkListLb,LinkList*Lc)

(

inti=l,j=l,k=O;

intLa_len,Lb」en;

ElemTypeai,bj;

InitList(Lc);

La_len=ListLength(La);

Lb_len=ListLength(Lb);

while(i(=La_len&&j<=Lb_len)//表La和表Lb均非空

(

GetElem(La,i,&ai);

GetElem(Lb,j,&bj);

if(ai<=bj)

(

Listinsert(Lc,++k,ai);

++i;

else

ListInsert(Lc,++k,bj);

++j;

)

)

while(i<=La_len)II表La非空且表Lb空

(

GetElem(La,i++,&ai);

Listinsert(Lc,++k,ai);

)

while(j<=Lb_len)//表Lb非空且表La空

(

GetElem(Lb,j++,&bj);

Listinsert(Lc,++k,bj);

}

)

*/

//算法2.12P31

//已知單鏈線性表La和Lb的元素按值非遞減排列。

//歸并La和Lb得到新的單鏈線性表Lc,Lc的元素也按值非遞減排列

voidMergeList(LinkListLa,LinkList*Lb,LinkList*Lc)

(

LinkListpa=La—〉next,pb=(*Lb)->next,pc;

*Lc=pc=La;〃用La的頭結(jié)點作為Lc的頭結(jié)點

while(pa&&pb)

(

if(pa—〉data(=pb—〉data)

(

pc—〉next=pa;

*Lc=pa;

pa=pa—〉next;

)

else

(

pc—〉next=pb;

pc=pb;

pb=pb-〉next;

)

}

pc->next=pa?pa:pb;//插入剩余段

free"Lb);//釋放Lb的頭結(jié)點

Lb=NULL;

//判斷是否相等的函數(shù),Union()用到

intequal(ElemTypec1,ElemTypec2)

(

if(cl==c2)

return1;

else

return0;

}

//算法2.1

//將所有在線性表Lb中但不在La中的數(shù)據(jù)元素插入到La中

voidUnion(LinkListLa,LinkListLb)

(

ElemTypee;

intLa_len,Lb_len;

inti;

La_len=ListLength(La);//求線性表的長度

Lb_len=ListLength(Lb);

for(i=l;i<=Lb_len;i++)

(

GetElem(Lb,i,&e);//取Lb中第i個數(shù)據(jù)元素賦給e

if(!LocateElem(La,e,equal))//La中不存在和。相同的元素,則插入之

Listinsert(&La,++La_len,e);

)

}

//數(shù)據(jù)元素判定函數(shù)(相等為1,否則為0)

intcomp(ElemTypecl,ElemTypec2)

{

if(cl==c2)

return1;

else

return0;

}

voidvisit(ElemTypec)

(

printf("%d”,c);

)

intmain()

(

LinkListL,La,Lb,Lc;

ElemTypee,eO,d;

inti,j,n,k;

〃初始化一個單鏈表

i=InitList(&L);

〃通過插入操作創(chuàng)建一個單鏈表

for(j=l;j<=5;j++)

i=ListInsert(&L,l,j);

〃調(diào)用visit函數(shù),對單鏈表進行遍歷

printf("在L的表頭依次插入1?5后:L=");

ListTraverse(L,visit);//依次對元素調(diào)用visit(),輸出元素的值

〃判斷單鏈表是否為空

i=ListEmpty(L);

printf("L是否空:i=%d(l:是0:否)\n",i);

//清空單鏈表

i=ClearList(L);

printf("清空L后:L=");

ListTraverse(L,visit);

〃判斷單鏈表是否為空

i=ListEmpty(L);

printf("L是否空:i=%d(1:是0:否)\n”,i);

〃再次通過插入操作創(chuàng)建一個單鏈表

for(j=l;j<=10;j++)

Listinsert(&L,j,j);

printf(w在L的表尾依次插入1?10后:L=");

ListTraverse(L,visit);

〃取得單鏈表的第5個元素

GetElem(L,5,&e);

printf("第5個元素的值為:%d\n",e);

〃在單鏈表中找到和j滿足comp函數(shù)關(guān)系的元素

for(j=O;j(=1;j++)

(

k=LocateElem(L,j,comp);

if(k)

printf("第%(1個元素的值為%d\n",k,j);

else

printf("沒有值為%<1的元素\n”,j);

)

〃找到某個元素的前驅(qū)

for(j=l;j<=2;j++)〃測試頭兩個數(shù)據(jù)

(

GetElem(L,j,&e0);//把第j個數(shù)據(jù)賦給eO

i=PriorElem(L,e0,&e);//求eO的前驅(qū)

if(i==-1)

printf("元素%d無前驅(qū)\n”,eO);

else

printf("元素%€1的前驅(qū)為:%d\n",e0,e);

}

〃找到某個元素的后繼

for(j=ListLength(L)-1;j<=ListLength(L);j++)//測試最后兩個數(shù)據(jù)

GetElem(L,j,&eO);〃把第j個數(shù)據(jù)賦給eO

i=NextElem(L,eO,&e);//求eO的后繼

if(i==—1)

printf("元素%d無后繼\n",eO);

else

printf("元素%d的后繼為:%d\n”,eO,e);

}

〃求單鏈表的表長

k=ListLength(L);〃k為表長

〃刪除操作

for(j=k+l;j>=k;j—)

(

i=ListDelete(&L,j,&e);〃刪除第j個數(shù)據(jù)

if(i==0)

printf("刪除第%d個數(shù)據(jù)失敗\n”,j);

else

printf("刪除的元素為:%d\n",e);

}

printf("依次輸出L的元素:“);

ListTraverse(L,visit);

〃銷毀單鏈表

DestroyList(&L);

printf("銷毀L后:L=%u\n\n",L);

printf(w按非降序建立n個元素的線性表L,請輸入元素個數(shù)n:");

scanf&n);

CreatAscend(&L,n);

printf("依次輸出L的元素:”);

ListTraverse(L,visit);

//按非降序插入元素10

InsertAscend(L,l0);

printf("按非降序插入元素10后,線性表L為:");

ListTraverse(L,visit);

〃在L的頭部插入12

HeadInsert(L>12);

〃在L的尾部插入9

Endinsert(L,9);

printf("在L的頭部插入12,尾部插入9后,線性表L為:");

ListTraverse(L,visit);

i=GetFirstElem(L,&e);

printf("第1個元素是:%d\n",e);

prinlf("請輸入要刪除的元素的值:”);

scanf("%d'',&e);

i=DeleteElem(L,e);

if(i)

printf("成功刪除%d!\n",e);

else

printf("不存在元素%d!\n”,e);

printfC線性表L為:”);

ListTraverse(L,visit);

printf("請輸入要取代的元素的序號元素的新值:”);

scanfT%d%d”,&n,&e);

ReplaceElem(L,n,e);

printf("線性表L為:“);

ListTraverse(L,visit);

DestroyList(&L);

printf("銷毀L后,按非升序重新建立n個元素的線性表L,請輸入”

”元素個數(shù)n(〉2):(');

scanf("%d”,&n);

CreatDescend(&L,n);

printf("依次輸出L的元素:");

ListTraverse(L,visit);

//按非升序插入元素10

InsertDescend(L,10);

printf("按非升序插入元素10后,線性表L為:”);

ListTraverse(L,visit);

printf("請輸入要刪除的元素的值:”);

scanff'%d",&e);

i=DeleteElem(L,e);

if(i)

printf("成功刪除%(1!\n",e);

else

printf("不存在元素%d!\n”,e);

printfC線性表L為:");

ListTraverse(L,visit);

DeleteFirst(L,&e);

DeleteTail(L,&d);

printf("刪除表頭元素%d和表尾元素%d后,線性表L為:",e,d);

ListTraverse(L,visit);

,,,,

printf(\n);

//測試算法2.11

n=3;

CreateList2(&La,n);//正位序輸入n個元素的值

printf("正位創(chuàng)建后La=");//輸出鏈表La的內(nèi)容

ListTraverse(La,visit);

CreateList(&Lb,n);〃逆位序輸入n個元素的值

printf("逆位創(chuàng)建后Lb*;//輸出鏈表Lb的內(nèi)容

ListTraverse(Lb,visit);

DestroyList(&La);

DestroyList(&Lb);

//測試算法2。12

//初始化一個單鏈表La

i=InitList(&La);

〃通過插入操作創(chuàng)建一個單鏈表

for(j=2;j(=10;j+=2)

i=ListInsert(&La,1,j);

printf("La=M);//輸出鏈表La的內(nèi)容

ListTraverse(La,visit);

〃初始化一個單鏈表

i=InitList(&Lb);

〃通過插入操作創(chuàng)建一個單鏈表

for(j=l;j<=10;j+=2)

i=ListInsert(&Lb,l,j);

printf("Lb=");〃輸出鏈表Lb的內(nèi)容

ListTraverse(Lb,visit);

〃按非遞減順序歸并La和Lb,得到新表Lc

MergeList(La,&Lb,&Lc);

printf("合并La和Lb后,Lc=M);

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論