什么是单链表?
由于顺序表在插入和删除是需要做大量的元素移动工作,而且需要连续的物理空间,因此其缺点是十分明显的,为了解决这一问题,不需要预先分配连续的内存地址空间、插入删除元素不需要做大量移动工作的链表出现了。但解决问题的同时也拥有自己的缺点,即不能随机存取。
在链表中,每个数据元素是一个节点,每个节点包含两部分,存续元素信息的数据域和存储后继节点存储位置的指针域。
其中,头指针指示链表中第一个节点的存储位置,头结点为在第一个元素前附设的一个节点,最后一个节点因为没有后继节点,因此指针域为空。
正是因为链表的这种结构,导致链表不可以随机访问数据元素,只能从第一个元素一个一个的访问,因此,对于单链表来说,插入删除元素是高效的,而访问元素是低效的。
以下为单链表的C语言实现。
需要提前定义好的内容
1 #include
2 #include
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 intElemType;
注意,malloc.h,是动态存储分配函数头文件,当对内存区进行操作时,要调用相关函数。
结点
1 typedef structLNode2 {3 intdata;4 LNode *next;5 }LNode,*LinkList;
使用结构体定义节点,包含数据域和指针域。
头插法建立单链表
1 void CreateList_L(LinkList &L,intn){2 //逆序输入n个元素的值,建立带表头节点的单链表L
3 L=(LinkList)malloc(sizeof(LNode));4 L->next=NULL;//先建立一个带头结点的单链表
5 inti;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,inti,ElemType e){2 //在带头结点的单链线性表L中第i个位置之前插入元素e
3 LinkList p=L;int j=0;4 while(p&&jnext;++j;6 }//寻找第i-1个节点
7 if(!p||j>i-1) returnERROR;8 LinkList s;9 s=(LinkList)malloc(sizeof(LNode));10 s->data=e;s->next=p->next;11 p->next=s;12 returnOK;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
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 returnOK;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&&jnext;++j;8 }9 if(!p||j>i) returnERROR;10 e=p->data;11 returnOK;12 }//GetElem_L
输出单链表的所有元素
voidprintL(LinkList L){
LinkList p;
p=L->next;while(p!=NULL){
printf("%d",p->data);
p=p->next;
}
}
main函数
1 intmain(){2 LinkList L;3 CreateList_L(L,4);//创建一个单链表,并指定单链表的长度。
4 printL(L);5 printf("\n");6 intinsert;7 printf("请输入要插入的元素:");8 scanf("%d",&insert);9 ListInsert_L(L,1,insert);10 printf("插入后的链表元素为:");11 printL(L);12 printf("\n");13 inta;14 inti;15 printf("请输入要删除第几个元素:");16 scanf("%d",&i);17 ListDelete_L (L,i,a);18 printL(L);19
20 }
以上是单链表的介绍。除此之外,还有很多其他形式的链表。
循环链表
双向链表
静态链表