双链表的基本操作
数组与链表的区别:
– | 数组 | 链表 |
---|---|---|
优点 | 1.数组静态内存分配,内存中地址连续 2.查找速度快 3.可以通过下标进行快速定位 | 1.插入删除速度快 2.内存利用率高,不浪费内存 3.拓展很灵活 |
缺点 | 1.插入和修改数据效率低,每次都需要移动其他数据 2.内存连续,必须有足够的内存空间 3.数组大小固定,不能动态拓展 4.可能存在内存浪费 | 1.查找效率低,必须从头遍历 |
下面是双链表的基本操作:
操作系统:Mac OS
IDE: Xcode
双链表与单链表操作基本类似,所以只写了部分操作具体代码如下:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct Node {
ElemType data;
struct Node* prior;
struct Node* next;
} NODE;
typedef NODE* nodePtr;
typedef struct DBList {
nodePtr head;
nodePtr tail;
int length;
} DBList;
typedef DBList* listPtr;
//初始化链表
listPtr initList() {
listPtr list = (listPtr)malloc(sizeof(DBList));
list -> head = NULL;
list -> tail = NULL;
list -> length = 0;
return list;
}
//创建节点
nodePtr createNode(ElemType data) {
nodePtr newNode = (nodePtr)malloc(sizeof(NODE));
if (newNode == NULL) {
printf("存储空间分配失败");
exit(0);
}
newNode -> data = data;
newNode -> prior = NULL;
newNode -> next = NULL;
return newNode;
}
//链表追加元素
void appendElemToDBList(listPtr list, ElemType data) {
nodePtr newNode = createNode(data);
if (list -> head == NULL) {
list -> head = newNode;
list -> tail = newNode;
} else {
list -> tail -> next = newNode;
newNode -> prior = list -> tail;
list -> tail = newNode;
}
list -> length ++;
}
int getDBListLength(listPtr list) {
return list -> length;
}
//插入元素
void insertElemToDBList(listPtr list, int index, ElemType data) {
int length = getDBListLength(list);
if (index < 0 || index > length) {
printf("输入有误!");
return;
}
if (index == 0) {
if (list -> head == NULL) {
appendElemToDBList(list, data);
} else {
nodePtr newNode = createNode(data);
newNode -> next = list -> head;
list -> head -> prior = newNode;
list -> head = newNode;
list -> length ++;
}
} else if (index == length) {
appendElemToDBList(list, data);
} else {
nodePtr newNode = createNode(data);
int i = 0;
nodePtr moveNode = list -> head;
while (moveNode != NULL && i < index) {
moveNode = moveNode -> next;
i++;
}
newNode -> prior = moveNode -> prior;
newNode -> next = moveNode;
moveNode -> prior -> next = newNode;
moveNode -> prior = newNode;
list -> length ++;
}
}
//遍历链表
void traverseList(listPtr list, void(*visit)(ElemType data)) {
if (list -> head == NULL) {
return;
}
nodePtr moveNode = list -> head;
while (moveNode != NULL) {
visit(moveNode -> data);
moveNode = moveNode -> next;
}
}
void nodePrint(ElemType data) {
printf("%d-->",data);
}
int main() {
listPtr list = initList();
printf("\n测试追加元素:--------------------------------\n");
for (int i = 0; i < 10; i++) {
appendElemToDBList(list, i);
}
traverseList(list, nodePrint);
printf("\n-------------------------------------------\n");
printf("\n测试插入元素:--------------------------------\n");
insertElemToDBList(list, 2, 100);
traverseList(list, nodePrint);
printf("\n-------------------------------------------\n");
printf("\n测试删除元素:--------------------------------\n");
printf("\n-------------------------------------------\n");
return 0;
}