單鏈表的C語言實現及插入刪除算法


  • 什么是單鏈表?

  由於順序表在插入和刪除是需要做大量的元素移動工作,而且需要連續的物理空間,因此其缺點是十分明顯的,為了解決這一問題,不需要預先分配連續的內存地址空間、插入刪除元素不需要做大量移動工作的鏈表出現了。但解決問題的同時也擁有自己的缺點,即不能隨機存取。

  在鏈表中,每個數據元素是一個節點,每個節點包含兩部分,存續元素信息的數據域和存儲后繼節點存儲位置的指針域。

  其中,頭指針指示鏈表中第一個節點的存儲位置,頭結點為在第一個元素前附設的一個節點,最后一個節點因為沒有后繼節點,因此指針域為空。

  

  正是因為鏈表的這種結構,導致鏈表不可以隨機訪問數據元素,只能從第一個元素一個一個的訪問,因此,對於單鏈表來說,插入刪除元素是高效的,而訪問元素是低效的。

  以下為單鏈表的C語言實現。

  • 需要提前定義好的內容
 1 #include<stdio.h>
 2 #include<malloc.h>
 3 #define SIZE  100
 4 #define  INCREMENT_SIZE 10
 5 #define TRUE    1
 6 #define FALSE    0
 7 #define OK        1
 8 #define ERROR    0
 9 #define    OVERFLOW -2
10 typedef int Status;//Status 代替了 int
11 typedef int ElemType;

  注意,malloc.h,是動態存儲分配函數頭文件,當對內存區進行操作時,要調用相關函數。

  • 結點
1 typedef struct  LNode
2 {
3    int data;
4    LNode *next;
5 }LNode,*LinkList;

  使用結構體定義節點,包含數據域和指針域。

  • 頭插法建立單鏈表
 1 void CreateList_L(LinkList &L,int n){
 2     //逆序輸入n個元素的值,建立帶表頭節點的單鏈表L
 3     L=(LinkList)malloc(sizeof(LNode));
 4     L->next=NULL;//            先建立一個帶頭結點的單鏈表
 5     int i;
 6     LinkList p;
 7     for(i=n;i>0;--i){
 8         p=(LinkList)malloc(sizeof(LNode));//生成新節點 
 9         printf("請輸入元素值:");
10         scanf("%d",&p->data);//輸入元素值 
11         p->next=L->next;L->next=p; //插入到表頭 
12     }
13 } //CreatList_L

  頭插法,每次插入元素時都在頭結點后面插入新的數據元素,因此,插入完成后的單鏈表的順序與插入的順序相反。與此相應還有尾插法。

  • 在指定位置插入數據元素
 1 Status ListInsert_L(LinkList &L,int i,ElemType e){
 2     //在帶頭結點的單鏈線性表L中第i個位置之前插入元素e
 3     LinkList p=L;int j=0;
 4     while(p&&j<i-1){
 5         p=p->next;++j;
 6     }//尋找第i-1個節點
 7     if(!p||j>i-1) return ERROR;
 8     LinkList s;
 9     s=(LinkList)malloc(sizeof(LNode));
10     s->data=e;s->next=p->next;
11     p->next=s;
12     return OK;
13 }//ListInsert_L 
  • 刪除第i個元素
 1 Status     ListDelete_L (LinkList &L,int i,ElemType &e){
 2     //在帶頭結點的單鏈表L中,刪除第i個元素,並由e返回其值
 3     LinkList p;
 4     LinkList q;
 5     p=L; int j=0;
 6     while(p->next&&j<i-1){//尋找第i個節點,並令p指向其前驅
 7         p=p->next;++j;
 8     }
 9     if(!(p->next)||j>i-1) return ERROR; //刪除位置不合理
10     q=p->next;p->next=q->next;//刪除並釋放節點 
11     e=q->data; free(q);
12     return OK; 
13      
14 }//ListDelete_L
  • 獲取第i個元素的值
 1 Status GetElem_L(LinkList L,int i,ElemType &e){
 2     //L為帶都節點的單鏈表的指針
 3     //當第i個元素存在時,其值賦給e並返回OK,否則返回ERROR
 4     LinkList p;
 5     p=L->next;int j=1;
 6     while(p&&j<i){
 7         p=p->next;++j;
 8     }
 9     if(!p||j>i) return ERROR;
10     e=p->data;
11     return OK;
12 }//GetElem_L
  • 輸出單鏈表的所有元素
void printL(LinkList L){
    LinkList p;
    p=L->next;
    while(p!=NULL){
        printf("%d ",p->data);
        p=p->next;
    }
    
}
  • main函數
 1 int main(){
 2     LinkList L;
 3     CreateList_L(L,4);//創建一個單鏈表,並指定單鏈表的長度。 
 4     printL(L);
 5     printf("\n");
 6     int insert;
 7     printf("請輸入要插入的元素:");
 8     scanf("%d",&insert); 
 9     ListInsert_L(L,1,insert);
10     printf("插入后的鏈表元素為:");
11     printL(L);
12     printf("\n");
13     int a;
14     int i; 
15     printf("請輸入要刪除第幾個元素:");
16     scanf("%d",&i); 
17     ListDelete_L (L,i,a);
18     printL(L);
19     
20 } 

  以上是單鏈表的介紹。除此之外,還有很多其他形式的鏈表。

  • 循環鏈表

  

 

  • 雙向鏈表

 

  • 靜態鏈表

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM