事先聲明:
由於這些鏈表的操作涉及到資料結構,所以很多函數的細節,我並沒有親自驗證,有興趣的同學可以給我提出寶貴的意見,在下不勝感激。
我感覺資料結構最終要的是思想。好了廢話不多說了,上代碼嘍。。
單鏈表的增刪改查
#include<stdio.h>int main(void){//鏈表的頭插法,設定插入節點為xx-next=head->next;head-next=x;//鏈表的尾插法,設定插入節點為x,設定鏈表最後一個節點為p(p->next=NULL)x->next=p->next;p->next=x;p=x;//重新把尾指標移到鏈表最後//鏈表的尋找,x所在鏈表沒有頭指標if(p->data==x->data){}//x所在鏈表有頭指標if(p->data==x->next->data){}//鏈表的刪除,設定刪除的鏈表節點為p,設定找到的相等的節點為q,q的前一個節點為preif(p->data==q->data){pre->next=q->next;}//第二種方法,實際上都是一樣的。r=pre->next;pre->next=pre->next->next;free(r);return 0;}
將遞增有序的兩個單鏈表合并
#include<stdio.h>//將遞增有序的兩個單鏈表合并Linklist MergeLinklist(Linklist La,Linklist Lb){Node *pa,*pb,*p;Linklist Lc;//鏈表的初始化操作pa=La->next;pb=Lb->next;//Lc表的初始化Lc=La;Lc->next=NULL;p=Lc;//開始合并單鏈表while(pa!=NULL&&pb!=NULL)//當兩個表都沒有處理完時{// 將較小的資料插入Lc鏈表中if(pa->data<=pb->data){p->next=pa;p=pa;pa=pa->next;//指標下移}else{p->next=pb;p=pb;pb=pb->next;//指標下移}}if(pa)//如果La表沒完p->next=pa;elsep->next=pb;free(Lb);return Lc;}
迴圈單鏈表的合并演算法
#include<stdio.h>//迴圈單鏈表的合并演算法1,兩個鏈表首尾相連Linklist merge1(Linklist la,Linklist lb)//代錶鏈表的頭指標{Node *p,*q;p=la;q=lb;while(p->next!=la) p=p->next;//找到la的鏈表結尾while(q->next!=lb) q=q->next;//找到lb的鏈表結尾q->next=la;//lb的尾指標指向la的前端節點p->next=lb->next;//la的尾指標指向lb的第一個節點free(lb);return la;}//迴圈單鏈表的合并演算法2,將第一個鏈表插入第二個鏈表Linklist merge2(Linklist ra,Linklist rb)//代錶鏈表的尾指標{Node *p;p=ra->next;//p成為了頭指標ra->next=rb->next->next;//將lb的開始節點插入la的終端結點之後free(rb->next);rb->next=p;//將la的頭結點連結到lb的終端結點之後return rb;}
單鏈表的逆置(沒有額外申請鏈資料表空間)
#include<stdio.h>//單鏈表的逆置(沒有額外申請鏈資料表空間)node *reverse(node *head){node *p1,*p2,*p3;if(head==NULL||head->next==NULL){return head;}p1=head;//代表頭結點p2=head->next;//代表第二個節點while(p2!=NULL){p3=p2->next;//將第二個節點儲存p2->next=p1;//將第二個節點指向第一個節點p1=p2;//將第一個節點放在逆置鏈表的頭p2=p3;//繼續迴圈原單鏈表}head->next=NULL;//head不指向任何節點head=p1;return head;}
雙向鏈表的建立,插入,刪除操作
#include<stdio.h>//雙向鏈表的建立,插入,刪除操作typedef struct student{int data;struct student *pre;struct student *next;}node;//建立雙向鏈表node create(){node *head,*p,*s;int x,cycle=1;head=(node *)malloc(sizeof(node));p=head;while(cycle){printf("\n請輸入資料data:");scanf("%d",&x);if(x==0){cycle=0;break;}s=(node *)malloc(sizeof(node));s->data=x;p->next=s;s->pre=p;p=s;}head=head->next;head->pre=NULL;p->next=NULL;return head;}//雙向鏈表插入節點node *insert(node *head,int data){node *x,*p;//x是要插入的節點p=head;//此處head筆者代表頭結點x=(node *)malloc(sizeof(node));x->data=data;while(p->next->data<x->data&&p->next!=NULL){p=p->next;}if(p->next==NULL){x->next=p->next;//順序串連p->next=x;x->next=p;//逆序串連x->pre=NULL;}else{x->next=p->next;//順序串連p->next=x;x->pre=p;//逆序串連x->next->pre=x;}return head;}//雙向鏈表的刪除node *deleteNode(node *head,int data){node *p1,*p2;p1=head;//此處head筆者不代表頭結點,代表第一個節點while(p1!=NULL&&p1->data!=data){p1=p1->next;}if(p1->data==data)//如果因為資料找到跳出迴圈,//需要注意:裡面可能還會出現首位節點的特殊情況,我們就不做討論了。//實際上因為head代表第一個節點而非頭結點,實際上下面的代碼也是正確的,// 但是為了更加的精確,盡量分情況寫出,我們這裡就不討論了。{p1->pre->next=p1->next;p1->next->pre=p1->pre;free(p1);}else//(p1->next==NULL)//如果因為迴圈到底沒找到,那麼說明沒有這個值{printf("不存在這個節點!!!");}}