链表
链表 = 数据 + 指针
数据:当前节点的数据。
指针:指向下一个节点。
整体结构:head-> 节点->NULL
结构定义
节点的定义
typedef struct Node {
int data;
struct Node *next;
}Node;
链表整体的定义
typedef struct List {
Node head; //虚拟头节点
int length;
}List;
链表的定义分为节点及其整体,这决定着对结构的一种操作都需要分两步进行。
结构的操作
创立一节点
Node *getNewNode(int val) {
Node *p = (Node *)malloc(sizeof(Node));
p->data = val;
p->next = NULL;
return p;
}
创立链表
typedef struct List {
Node head; //虚拟头节点
int length;
}List;
链表仅仅包含头(使用虚拟头节点,方便后续的操作),而末尾的NULL
由节点前继。
节点的插入
插入一个节点,要是该节点移动到,被插入节点的前一处,然后插入节点的next指向被插入节点的地址,随后将前一节点的next指向,插入的节点的地址。
int insert(List *l, int ind, int val) {
if (l ==NULL) return 0;
if (ind < 0 || ind > l->length) return 0;
Node *p = &(l->head), *node = getNewNode(val);
while (ind--) p = p->next;
node->next = p->next;
p->next = node;
l->length += 1;
return 1;
}
其中while (ind--) p = p->next;
就是将其节点移动到被插入节点的前一处。
删除节点
删除节点,将前一节点的next指向删除节点的next ,随后删除节点。
int erase(List *l, int ind) {
if (l == NULL) return 0;
if (ind < 0 || ind >= l->length) return 0;
Node *p = &(l->head), *q;
while(ind--) p = p->next;
q = p->next;
p->next = q->next;
clear_node(q);
l->length -= 1;
return 1;
}
void clear_node(Node *node) {
if(node == NULL) return ;
free(node);
return ;
}
清除链表
void clear(List *l) {
if(l == NULL) return ;
Node *p = l->head.next, *q;
while(p != NULL) {
q = p->next;
clear_node(p);
p = q;
}
free(l);
return ;
}
链表的反转
void reverse(List *l) {
if (l == NULL) return ;
Node *p = l->head.next, *q;
l->head.next = NULL;
while (p != NULL) {
q = p->next;
p->next = l->head.next;
l->head.next = p;
p = q;
}
return ;
}
链表的输出
void output(List *l) {
if (l == NULL) return ;
printf("list(%d) : ", l->length);
for(Node *p = l->head.next; p != NULL; p = p->next) {
printf("%d->", p->data);
}
printf("NULL\n");
return ;
}
完整代码
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
typedef struct Node {
int data;
struct Node *next;
}Node;
typedef struct List {
Node head; //虚拟头节点
int length;
}List;
Node *getNewNode(int);
List *init_list();
void clear_node(Node *);
void clear(List *);
int insert(List *, int, int);
int erase(List *, int);
void output(List *);
Node *getNewNode(int val) {
Node *p = (Node *)malloc(sizeof(Node));
p->data = val;
p->next = NULL;
return p;
}
List *init_list() {
List *l = (List *)malloc(sizeof(List));
l->head.next = NULL;
l->length = 0;
return l;
}
int insert(List *l, int ind, int val) {
if (l ==NULL) return 0;
if (ind < 0 || ind > l->length) return 0;
Node *p = &(l->head), *node = getNewNode(val);
while (ind--) p = p->next;
node->next = p->next;
p->next = node;
l->length += 1;
return 1;
}
int erase(List *l, int ind) {
if (l == NULL) return 0;
if (ind < 0 || ind >= l->length) return 0;
Node *p = &(l->head), *q;
while(ind--) p = p->next;
q = p->next;
p->next = q->next;
clear_node(q);
l->length -= 1;
return 1;
}
void clear_node(Node *node) {
if(node == NULL) return ;
free(node);
return ;
}
void clear(List *l) {
if(l == NULL) return ;
Node *p = l->head.next, *q;
while(p != NULL) {
q = p->next;
clear_node(p);
p = q;
}
free(l);
return ;
}
void reverse(List *l) {
if (l == NULL) return ;
Node *p = l->head.next, *q;
l->head.next = NULL;
while (p != NULL) {
q = p->next;
p->next = l->head.next;
l->head.next = p;
p = q;
}
return ;
}
void output(List *l) {
if (l == NULL) return ;
printf("list(%d) : ", l->length);
for(Node *p = l->head.next; p != NULL; p = p->next) {
printf("%d->", p->data);
}
printf("NULL\n");
return ;
}
int main() {
srand(time(0));
#define MAX_OP 20
List *l = init_list();
for (int i = 0; i < MAX_OP; i++) {
int op = rand() % 4;
int val = rand() % 100;
int ind = rand() %(l->length +3) -1;
switch (op) {
case 0:
case 1: {
printf("insert %d at %d to list = %d\n", val, ind, insert(l, ind, val));
}break;
case 2: {
printf("reverse the list\n");
reverse(l);
}break;
case 3: {
printf("erase a item at %d from List = %d\n", ind, erase(l, ind));
}break;
}
output(l), printf("\n");
}
#undef MAX_OP
clear(l);
return 0;
}