单链表的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 } 

  以上是单链表的介绍。除此之外,还有很多其他形式的链表。

  • 循环链表

  

  • 双向链表

  • 静态链表

 

猜你喜欢

转载自www.cnblogs.com/freeurmind/p/9932262.html
今日推荐