1. 程式人生 > >連結串列(包括特殊的連結串列-棧和佇列)

連結串列(包括特殊的連結串列-棧和佇列)

總結一下連結串列的用法,加深自己的印象也給自己和其他萌新做參考。

連結串列其實跟陣列一樣,都是線性表的一類,不同的在於陣列是順式儲存結構,而連結串列則是鏈式儲存結構,為什麼有時候要用連結串列呢?因為連結串列在插入和刪除元素的時候比陣列更加有優勢,並且它不用擔心溢位的問題。當然能用陣列解決的問題,就儘量別用連結串列了,因為連結串列功能的實現方面還是相對麻煩的。(個人意見)

一 單鏈表

首先最簡單的連結串列,單鏈表,由結點組成,結點中包含資料域(放資料)和指標域(指向下一個結點的地址,從而達到連起來的效果),首先要建立一個連結串列,要先有一個頭指標(而頭結點不是必要的)。

/*線性表的單鏈表儲存結構*/
typedef int ElemType;/*typedef 起到起別名的作用,以int為例,實際情況請靈活變通一下。
typedef struct Node
{
      ElemType data;/*資料域*/
      struct Node *next;/*指標域*/
}Node;
typedef struct Node *LinkList;/*定義LickList,後面宣告指標用的*/
        

這個是建立結點用的結構體。(連結串列必要元素)

然後接著就是連結串列的建立了

/*假設一個首項為一,公差為一的遞增數列輸入到連結串列裡,假設有8項*/
void CreatListHead(LinkList *L , int n)/*頭插法,後入的編號在前面
{
      LinkList p;
      int i;
      *L = (LinkList)malloc(sizeof(Node));
      (*L)->next=NULL;        /*先建立一個帶頭結點的單鏈表*/
      for(i=0;i<8;i++){
           p=(LinkList)malloc(sizeof(Node));/*建立一個新結點,malloc的頭問題是stdlib.h*/
           p->data=i+1;
           p->next=(*L)->next;
           (*L)->next=p;         /*相當於L的手不要NULL了,牽了p,而p牽了NULL*/
        }
}


連結串列資料的輸入也可以在主函式裡面,看個人,輸入跟插入其實差不多。

後插法比較符合我們的正常思維,多了個指向尾部的指標,程式碼如下:

void CreatListTail(LinkList *L , int n )
{
      LinkList p,r;/*r為指尾部的指標*/
      int i;
      *L=(LinkList)malloc(sizeof(Node));
      r=*L;
      for(i=0;i<8;i++){
           p=(LinkList)malloc(sizeof(Node));
           p->data=i+1;
           r->next=p;
           r=p;
      }
      r->next=NULL;     /*表示連結串列結束 */
}
     

接下來介紹一下單鏈表的插入和刪除。

插入就相當於把一個位置讓給一個結點,這個位置的前面的結點把指標指向它,而這個插入的結點把指標指向後面的結點。

程式碼如下:

void InsertList(LinkList *L , int i ,  ElemType e )/* i為插入位置,e為插入的值*/
{
        LinkList p,s;
        int j=1;
        p=*L;
        while(p&&j<i){
        p=p->next;
        ++j;
        }
        if(!p||j>i)
        return  ERROR;
        s=(LinkList)malloc(sizeof(Node));
        s->data=e;
        s->next=p->next;/*將p的後繼結點賦給s的後繼*/
        p->next=s;/*p的後繼指標指向s*/
        return OK;
}
         

刪除則是反過來,可以看作忽略掉要刪除位置的結點,然後其前面的結點的指標去指向其後面即可。需要去回收要刪除的結點(free)。

程式碼如下:

void DeleteList (LinkList *L,int i,ElemType *e)/*需要返回刪除的值e*/
{
        LinkList p,q;
        int j;
        p=*L;
        while(p&&j<i){
           p=p->next;
           ++j;
        }
        if(!p|j>i)
        return ERROR;
        q=p->next;/*p為刪除位置的前一位,q為刪除位置*/
        p->next=q->next;/*p的後繼指標指向刪除位置q的後繼指標,即跳過q*/
        *e=q->data;
        free(q);/*其功能與malloc相反*/
        return OK;
}