如图所示,可以看到组成链表的部分是一个个包含有元素和指针的结构体组成的,其中每一个结构体包含了本身所存储的元素,以及一个指向下一个结构体的指针,通过这种单项链表的结构,在插入与删除元素的操作复杂度上,相比于简单的数组要简单得多。因为,对于数组元素的插入和删除,对于其后续的元素都需要进行相移的前移或者后移,而链表只需要在该元素的前节点和后节点进行指针的改写(或存在元素的释放),即可完成操作
![](https://i-blog.csdnimg.cn/blog_migrate/59408cdf405dd605df7007d810f047ef.png)
当然相比可以进行随机访问的数组而言,只能进行顺序访问的链表就显得有些繁琐,链表的访问需要通过由头节点通过指针进行顺序查找。
以下为单向链表实现代码
链表定义与初始化函数:
#include <stdio.h>
#include <stdlib.h>
typedef int E;
struct ListNode{
E element;
struct ListNode * next;
};
typedef struct ListNode * ArrayNode;
void initListNode(ArrayNode node){
node->next = NULL;
}
插入链表元素函数:
_Bool insertNode(ArrayNode head, E element, int index){
if (index < 1) return 0;
while (--index){
head = head->next;
if (head == NULL) return 0;
}
ArrayNode newhead = malloc(sizeof(struct ListNode));
if(newhead == NULL) return 0;
newhead->element=element;
if(head->next != NULL){
newhead->next = head->next;
}
head->next = newhead;
return 1;
}
此处采用malloc函数对新元素空间进行申请,并且对删除节点是否为尾节点进行判断,减少操作
删除链表元素函数:
_Bool deleteNode(ArrayNode head, int index){
if(index<1) return 0;
while(--index){
head = head->next;
if(head == NULL) return 0;
}
ArrayNode tmp = head->next;
head->next=head->next->next;
free(tmp);
return 1;
}
按顺序打印链表所有元素:
void printList(ArrayNode node){
while(node->next){
node = node->next;
printf("%d\n", node->element);
printf("\n");
}
}
主函数测试:
int main(){
struct ListNode head;
initListNode(&head);
int i;
for(i=1; i<5; ++i){
insertNode(&head, i*100, i);
}
printList(&head);
deleteNode(&head, 2);
printList(&head);
}
得到测试结果:
100
200
300
400
100
300
400