帶頭結點和不帶頭結點的單鏈表的尾插法以及各種操作

來源:互聯網
上載者:User

 

一.帶頭結點的單鏈表

先說一下create()建立的鏈表,採用cycle的方式。

/*************************************************************帶頭結點的單鏈表13-1-1ex3.cpp1.建立單鏈表2.求鏈表長度3.在第i個位置插入元素(種方法)4.刪除指定序號的節點由於本程式是帶前端節點的,所以在刪除函數Del()和插入函數InsertList()中,head均沒有被改變,所以,主函數中,用了Del和InsertList之後均沒有改變head,在PrintList中,還可以繼續把head傳入。如果是這樣的話,這兩個函數完全可以定義成void類型,而不是Node *類型的只要將Create()定義成Node *就行,再在main()中定義一個指標head將head=Create();以後這個head都不會變了。好像帶前端節點鏈表的這些常規操作均不改變Head節點。**************************************************************/#include<stdio.h>#include<stdlib.h>//#include<string.h>//#include<conio.h> typedef struct student{         int data;         struct student *next;         //struct student *pre;}Node;  int GetLength(Node *head){         int n=0;         Node *p;         p=head->next;         while(p!=NULL)         {                  p=p->next;                  n++;         }         return n;} Node *InsertList(Node *head, int x, int i) //插入元素方法1{         Node *p, *q, *s;         int j=1;         p=head;         if(i<1 || i>GetLength(head)+1)         {                  exit(1);         }         s=(Node *)malloc(sizeof(Node));         s->data=x;         while(j<=i)         {                  q=p;                  p=p->next;                  j++;         }         s->next=q->next;         q->next=s;         return head;} void  InsertList2(Node *head, int x, int i) //插入元素方法2{         Node *p,*s;         int j=1;         p=head;         if(i<1 || i>GetLength(head)+1) //這塊兒比刪除節點函數多加了一個,因為可以插入到最後一個節點的後面一個節點。但是刪除節點函數不行,只能刪除到最後一個節點         {                  exit(1);         }         s=(Node *)malloc(sizeof(Node));         s->data=x;         while(j<i)         {                  p=p->next;                  j++;         }         s->next=p->next;         p->next=s;         //return head;}Node *Del(Node *head, int i){         Node *p, *q;         int j=1;         p=head;         if(i<1 || i>GetLength(head))         {                  exit(1);         }         while(j<i)         {                  p=p->next;                  j++;         }         q=p->next;         p->next=q->next;         free(q);         return head;} Node *create(){         Node *head, *p, *s;         int x, cycle=1;         head=(Node *)malloc(sizeof(Node));         p=head; //如果換成帶前端節點的鏈表。這裡也不能變,切記,不能變成p=head->next;那就錯了         printf("\nplease input the data:\n");         while(cycle)         {                  //printf("\nplease input the data:\n");                  scanf("%d",&x);                  if(x!=0)                  {                          s=(Node *)malloc(sizeof(Node));                          s->data=x;                          //printf("\n %d", s->data);                          p->next=s;                          //s->pre=p;                          p=s;                  }                  else                  {                          cycle=0;                  }         }         p->next=NULL;         //head=head->next;//注意,這句是不帶頭結點的單鏈表必須做的,因為按照演算法。輸入的第一個數實際上是賦值給了head->next         //printf("\nhead->data:%d\n",head->data);         return head;} void PrintList(Node *head) //列印鏈表的所有元素{         Node *p;         p=head->next; //1)         while(p!=NULL)         {                  printf("%3d", p->data);                  p=p->next;         }         printf("\n");} int main(){         Node *p, *q ,*t, *head;         head=create();         //p=p->next;//如果是帶前端節點的單鏈表建立,除了少了上面那個函數的末尾的步之外,多了這一步,保證從head的下一個節點輸出鏈表data。         printf("\nnow output the linklist:\n");         PrintList(head);                 InsertList2(head, 99,3);         //q=q->next;         printf("\nnow output the new linklist after INSERT:\n");         PrintList(head);         /*         while(q!=NULL)         {                  printf("%3d",q->data);                  q=q->next;         }         printf("\n");         */                  Del(head, 3);         printf("\nnow output the new linklist after DELETE:\n");         PrintList(head);         /*         t=t->next;         while(t!=NULL);         {                  printf("%3d",t->data);                  t=t->next;         }         printf("\n");         */         system("pause");         return 0;}

 

運行結果如下:

1.輸入為1 2 3 4 5 6。在第三個位置上插入一個數99,然後刪除第3個節點(0為結束控制符)

2.輸入為1 2。在第3個位置上,插入一個數99,然後刪除第三個節點(0為結束控制符)

 

再說一下create2()建立的鏈表,採用傳統的getchar()方式。

如果用create2()來建立,也很簡單。create2()函數可以直接加在這個程式裡面,另外再改動不多的幾個地方就行,也就是把輸入類型和PrintList中的輸出類型改為char以及%c就行了,途中黃色高亮部分標記的就是要改的。

下面看一下create2()代碼:

Node *create2(){         DataType x;         Node *head=(Node *)malloc(sizeof(Node));         Node *s, *r;         r=head;         while((x=getchar())!='\n') //注意,這個可是getchar()字元輸入的。必須按照順序輸入,不能按空格也不能按斷行符號,不然都會被當做一個字元         {                                                                                     //getchar()把空格也當成一個字元,這點與scanf不同。比如輸入:abcdefg斷行符號。不能這樣輸入:a b c d e f g斷行符號。                  s=(Node *)malloc(sizeof(Node));                  s->data=x;                  r->next=s;                  r=s; //r始終指向尾部節點         }         r->next=NULL;         return head;}

 

這麼看來,2種方法都不錯。

還有一點注意就是在插入的時候插入的是字元。別忘了加一個’ ‘。InsertList2(head, 'u',3);

運行結果:

1.      輸入abcdefg

2.      輸入1234567

 

 

二.不帶頭結點的單鏈表

說明:基本操作一樣,只不過有些差別。

1.      在Create()中的p->next=NULL;之後,加一句head=head->next;也就是將頭指標head後移。

2.      在PrintList()中,就沒有p=head->next;了直接就p=head;了。

3.      在InsertList()中,需要分3中情況討論:

a)       所插入的位置是首節點(head所指結點);

b)       所插入的位置是中間結點;

c)        所插入的位置是尾節點。

4.      在Del()中,需要分2種情況討論:

a)       所插入位置是首節點(head所指結點);

b)       所插入位置是其他節點(中間節點或者尾節點)。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.