单链表操作(c语言版)
-
数据结构
- 单链表分为两种,一种是带头节点是NULL的单链表,一种是头节点不是NULL的单链表
- 单链表分为两种,一种是带头节点是NULL的单链表,一种是头节点不是NULL的单链表
-
具体实现(可运行)
- 了解它的数据结构后,根据它特有的数据结构可以进行各种操作.
#include<stdio.h>
#include<stdlib.h>
typedef int ElemType;
//链表结构
typedef struct node {
ElemType data;
struct node *next;
} Node, *LinkList;
//遍历链表
void print(LinkList *root) {
Node *p;
p = *root;
printf("链表输出:");
p = p->next;
while (p != NULL) {
printf(" %d", p->data);
p = p->next;
}
printf("\n");
}
//初始化链表
void initLinkList(LinkList *root) {
*root = (LinkList) malloc(sizeof(Node));
(*root)->next = NULL;
printf("链表初始化成功.\n");
}
//头插法创建链表
void createLinkListHead(LinkList *root, ElemType data) {
Node *currNode;
currNode = (Node*) malloc(sizeof(Node));
currNode->data = data;
//1、先连接
currNode->next = (*root)->next;
//2、后断开
(*root)->next = currNode;
}
//尾插法创建链表
void createLinkListTail(LinkList *root, ElemType data) {
Node *currNode, *p;
p = *root;
//1、寻找尾节点
while (p->next != NULL) {
p = p->next;
}
currNode = (Node*) malloc(sizeof(Node));
currNode->data = data;
currNode->next = NULL;
//2、先连接
p->next = currNode;
//3、后断开
p = currNode;
}
//获取链表长度
int getListLength(LinkList *root) {
int length = 0;
Node *p;
p = (*root)->next;
while (p != NULL) {
p = p->next;
length++;
}
return length;
}
//指定位置插入节点
void insertList(LinkList *root, int i, ElemType data) {
Node *p, *currNode;
p = *root;
int length = getListLength(&(*root));
//1、检查插入的位置是否合适
if (i < 1 || i > length) {
printf("插入位置不符合.\n");
return;
}
//2、寻找插入的位置
for (int j = 1; j < i && p->next != NULL; ++j) {
p = p->next;
}
//3、插入节点
currNode = (Node*) malloc(sizeof(Node));
currNode->data = data;
currNode->next = p->next;
p->next = currNode;
printf("插入节点成功.\n");
}
//反转链表,定义一个新尾部q,把所有的节点使用头插法,插入到新尾部,最后再把尾部插入到头节点上
void revertList(LinkList *root) {
Node *p, *q, *temp;
p = (*root)->next;
//q为新链表的尾部
q = NULL;
while (p != NULL) {
//1、保存当前节点的下一个节点地址
temp = p->next;
//2、连接到新尾部
p->next = q;
//3、新尾部更新
q = p;
//4、指针移动到下一个节点
p = temp;
}
//5、新尾部连接到头节点上
(*root)->next = q;
}
//指定位置删除节点
void deleteList(LinkList *root, int i) {
Node *p, *y;
p = *root;
int length = getListLength(&(*root));
//1、判断位置是否能被删除
if (i < 1 || i > length) {
printf("删除位置不符合.\n");
return;
}
//2、寻找删除的位置
for (int j = 1; j <= i && p->next != NULL; ++j) {
y = p;
p = p->next;
}
y->next = p->next;
free(p);
printf("删除节点成功.\n");
}
//清空链表
void clearList(LinkList *root) {
Node *p, *temp;
p = (*root)->next;
while (p != NULL) {
temp = p;
p = p->next;
free(temp);
}
(*root)->next = NULL;
printf("清空链表成功.\n");
}
int main() {
//初始化链表
LinkList root;
initLinkList(&root);
//头插法
createLinkListHead(&root, 7);
createLinkListHead(&root, 8);
createLinkListHead(&root, 9);
print(&root);
//尾插法
createLinkListTail(&root, 6);
createLinkListTail(&root, 5);
createLinkListTail(&root, 4);
print(&root);
//获取链表长度
int length = getListLength(&root);
printf("链表长度: %d\n", length);
//插入节点
insertList(&root, 3, 11);
print(&root);
insertList(&root, 7, 10);
print(&root);
insertList(&root, 1, 20);
print(&root);
//删除节点
deleteList(&root, 1);
print(&root);
deleteList(&root, 7);
print(&root);
deleteList(&root, 3);
print(&root);
//反转链表
revertList(&root);
print(&root);
//清空链表
clearList(&root);
print(&root);
return 0;
}