C語言數(shù)據(jù)結(jié)構(gòu) 雙向鏈表的建立與基本操作
C語言數(shù)據(jù)結(jié)構(gòu) 雙向鏈表的建立與基本操作
雙向鏈表比單鏈表有更好的靈活性,其大部分操作與線性表相同。下面總結(jié)雙向鏈表與單鏈表之間的不同之處及我在實現(xiàn)過程中所遇到的問題。
1.雙向鏈表的建立
雙向鏈表在初始化時,要給首尾兩個節(jié)點分配內(nèi)存空間。成功分配后,要將首節(jié)點的prior指針和尾節(jié)點的next指針指向NULL,這是十分關(guān)鍵的一步,因為這是之后用來判斷空表的條件。同時,當鏈表為空時,要將首節(jié)點的next指向尾節(jié)點,尾節(jié)點的prior指向首節(jié)點。
2.雙向鏈表的插入操作
由于定義雙向鏈表時指針域中多了一個prior指針,插入操作相應變得復雜,但基本操作也并不難理解。只需記住在處理前驅(qū)和后繼指針與插入節(jié)點的關(guān)系時,應始終把握好“有序原則”,即若將插入節(jié)點與兩個已存在的節(jié)點構(gòu)成三角形,則應先處理“向上”的指針,再處理“向下”的指針。下面用代碼描述其過程:
pinsert->prior=p; pinsert->next=p->next; p->next->prior=pinsert; p->next=pinsert;
3.雙向鏈表的刪除操作
理解了雙向鏈表的插入操作后,刪除操作便十分容易理解。下面用代碼描述其過程:
p->prior->next=p->next; p->next->prior=p->prior; free(p);
雙向鏈表的其他操作與單鏈表類似,在此不再贅述,完整的代碼如下:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int status;
typedef int elemtype;
typedef struct node{
elemtype data;
struct node * next;
struct node * prior;
}node;
typedef struct node* dlinklist;
status visit(elemtype c){
printf("%d ",c);
}
/*雙向鏈表初始化*/
status initdlinklist(dlinklist * head,dlinklist * tail){
(*head)=(dlinklist)malloc(sizeof(node));
(*tail)=(dlinklist)malloc(sizeof(node));
if(!(*head)||!(*tail))
return ERROR;
/*這一步很關(guān)鍵*/
(*head)->prior=NULL;
(*tail)->next=NULL;
/*鏈表為空時讓頭指向尾*/
(*head)->next=(*tail);
(*tail)->prior=(*head);
}
/*判定是否為空*/
status emptylinklist(dlinklist head,dlinklist tail){
if(head->next==tail)
return TRUE;
else
return FALSE;
}
/*尾插法創(chuàng)建鏈表*/
status createdlinklisttail(dlinklist head,dlinklist tail,elemtype data){
dlinklist pmove=tail,pinsert;
pinsert=(dlinklist)malloc(sizeof(node));
if(!pinsert)
return ERROR;
pinsert->data=data;
pinsert->next=NULL;
pinsert->prior=NULL;
tail->prior->next=pinsert;
pinsert->prior=tail->prior;
pinsert->next=tail;
tail->prior=pinsert;
}
/*頭插法創(chuàng)建鏈表*/
status createdlinklisthead(dlinklist head,dlinklist tail,elemtype data){
dlinklist pmove=head,qmove=tail,pinsert;
pinsert=(dlinklist)malloc(sizeof(node));
if(!pinsert)
return ERROR;
else{
pinsert->data=data;
pinsert->prior=pmove;
pinsert->next=pmove->next;
pmove->next->prior=pinsert;
pmove->next=pinsert;
}
}
/*正序打印鏈表*/
status traverselist(dlinklist head,dlinklist tail){
/*dlinklist pmove=head->next;
while(pmove!=tail){
printf("%d ",pmove->data);
pmove=pmove->next;
}
printf("\n");
return OK;*/
dlinklist pmove=head->next;
while(pmove!=tail){
visit(pmove->data);
pmove=pmove->next;
}
printf("\n");
}
/*返回第一個值為data的元素的位序*/
status locateelem(dlinklist head,dlinklist tail,elemtype data){
dlinklist pmove=head->next;
int pos=1;
while(pmove&&pmove->data!=data){
pmove=pmove->next;
pos++;
}
return pos;
}
/*返回表長*/
status listlength(dlinklist head,dlinklist tail){
dlinklist pmove=head->next;
int length=0;
while(pmove!=tail){
pmove=pmove->next;
length++;
}
return length;
}
/*逆序打印鏈表*/
status inverse(dlinklist head,dlinklist tail){
dlinklist pmove=tail->prior;
while(pmove!=head){
visit(pmove->data);
pmove=pmove->prior;
}
printf("\n");
}
/*刪除鏈表中第pos個位置的元素,并用data返回*/
status deleteelem(dlinklist head,dlinklist tail,int pos,elemtype *data){
int i=1;
dlinklist pmove=head->next;
while(pmove&&i<pos){
pmove=pmove->next;
i++;
}
if(!pmove||i>pos){
printf("輸入數(shù)據(jù)非法\n");
return ERROR;
}
else{
*data=pmove->data;
pmove->next->prior=pmove->prior;
pmove->prior->next=pmove->next;
free(pmove);
}
}
/*在鏈表尾插入元素*/
status inserttail(dlinklist head,dlinklist tail,elemtype data){
dlinklist pinsert;
pinsert=(dlinklist)malloc(sizeof(node));
pinsert->data=data;
pinsert->next=NULL;
pinsert->prior=NULL;
tail->prior->next=pinsert;
pinsert->prior=tail->prior;
pinsert->next=tail;
tail->prior=pinsert;
return OK;
}
int main(void){
dlinklist head,tail;
int i=0;
elemtype data=0;
initdlinklist(&head,&tail);
if(emptylinklist(head,tail))
printf("鏈表為空\n");
else
printf("鏈表不為空\n");
printf("頭插法創(chuàng)建鏈表\n");
for(i=0;i<10;i++){
createdlinklisthead(head,tail,i);
}
traverselist(head,tail);
for(i=0;i<10;i++){
printf("表中值為%d的元素的位置為",i);
printf("%d位\n",locateelem(head,tail,i));
}
printf("表長為%d\n",listlength(head,tail));
printf("逆序打印鏈表");
inverse(head,tail);
for(i=0;i<10;i++){
deleteelem(head,tail,1,&data);
printf("被刪除的元素為%d\n",data);
}
traverselist(head,tail);
if(emptylinklist(head,tail))
printf("鏈表為空\n");
else
printf("鏈表不為空\n");
printf("尾插法創(chuàng)建鏈表\n");
for(i=0;i<10;i++){
//inserttail(head,tail,i);
createdlinklisttail(head,tail,i);
}
traverselist(head,tail);
printf("逆序打印鏈表");
inverse(head,tail);
}
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
上一篇:淺談int8_t int64_t size_t ssize_t的相關(guān)問題(詳解)
欄 目:C語言
下一篇:C語言實現(xiàn)數(shù)據(jù)結(jié)構(gòu)和雙向鏈表操作
本文標題:C語言數(shù)據(jù)結(jié)構(gòu) 雙向鏈表的建立與基本操作
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/1694.html
您可能感興趣的文章
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用函數(shù)刪除字符
- 04-02c語言的正則匹配函數(shù) c語言正則表達式函數(shù)庫
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言中對數(shù)函數(shù)的表達式 c語言中對數(shù)怎么表達
- 04-02c語言用函數(shù)寫分段 用c語言表示分段函數(shù)
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排序法函數(shù)
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段函數(shù)
- 04-02C語言中怎么打出三角函數(shù) c語言中怎么打出三角函數(shù)的值
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求階乘


閱讀排行
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對數(shù)函數(shù)的表達式 c語言中對
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機閱讀
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-11ajax實現(xiàn)頁面的局部加載
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10delphi制作wav文件的方法
- 01-10C#中split用法實例總結(jié)
- 04-02jquery與jsp,用jquery
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置


