数据结构之动态链表
链表的概念
逻辑结构上一个挨一个的数据,在实际存储时,并没有像顺序表那样也相互紧挨着。恰恰相反,数据随机分布在内存中的各个位置,这种存储结构称为线性表的链式存储。
链表和数组的作用相同,都是用来存储数据。数组在C语言中是一种很常见的数据结构,它是用来存储数据的,但是数组是一次分配完全部内存,而链表则是在需要时再分配内存,每次只分配出一个节点(Node)的内存,链表是由多个节点组成的,而每个节点都有俩个部分:数据区和指针区。
数据区:数据区是用来存储数据。
指针区:指针区是用来存储指向下一节点的指针。
链表:
头指针:永远指向链表中第一个结点的位置(如果链表有头结点,头指针指向头结点;否则,头指针指向首元结点)。
首元结点:链表中第一个元素所在的结点,它是头结点后边的第一个结点。即图中第二部分图形。
头结点:有时,在链表的第一个结点之前会额外增设一个结点,结点的数据域一般不存放数据(有些情况下也可以存放链表的长度等信息),此结点被称为头结点。但此图没有定义头节点。
单链表中可以没有头结点,但是不能没有头指针,头指针是必须的。
一般有头节点的链表是这样的:
向链表中加入节点
有三种方法:
- 插入到链表的头部,也就是头结点和首元结点中间;
- 插入到链表中间的某个位置;
- 插入到链表最末端;
下方代码为第一种插入方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| #include <stdio.h> #include <stdlib.h>
struct Node { int data; struct Node* next; };
struct Node* createList() { struct Node* headNode = (struct Node*)malloc(sizeof(struct Node)); headNode->next = NULL; return headNode; }
struct Node* createNode(int data) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = data; newNode->next = NULL; return newNode; }
void printList(struct Node* headNode) { struct Node* pMove = headNode->next; while (pMove) { printf("%d\t", pMove->data); pMove = pMove->next; } printf("\n"); }
void insertNodeByHead(struct Node* headNode, int data) { struct Node* newNode = createNode(data); newNode->next = headNode->next; headNode->next = newNode; }
void deleteNodeByAppoin(struct Node* headNode, int posData) { struct Node* posNode = headNode->next; struct Node* posNodeFront = headNode; if (posNode == NULL) { printf("无法删除,列表为空\n"); } else { while (posNode->data != posData) { posNodeFront = posNode; posNode = posNodeFront->next; if (posNode == NULL) { printf("未找到指定位置,无法删除\n"); return; } } posNodeFront->next = posNode->next; free(posNode); } }
int main() { struct Node* list = createList(); insertNodeByHead(list, 1); insertNodeByHead(list, 2); insertNodeByHead(list, 3); printList(list); deleteNodeByAppoin(list, 2); printList(list); system("pause"); return 0; }
|
打印结果:
因为是顺序插入的,所以3在最前面。