我是在哔哩哔哩的 up主TyrantLucifer 的手撕数据结构课程上学习的,个人感觉非常不错,大家也可以去学习,适合有c语言基础的。
注意:未考虑到malloc开辟空间错误或者取参数错误所发生的情况
1.定义一个结点结构体类型 并创建空表
#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
typedef struct Node
{
int data; //结点数据
struct Node * next; //next指针指向下一个结点
struct Node* pre; //pre指针指向前一个结点
}Node;
//创建空链表
Node * intList()
{
Node* L = (Node*)malloc(sizeof(Node));// 开辟新空间给头结点
L->data = 0;
L->next = NULL; // 空链表地址为空
L->pre = NULL;
return L; 返回头结点 地址
}
2.头插法
//头插法
void headInsert(Node * L,int data)
{
Node* node = (Node*)malloc(sizeof(Node)); // 定义一个新结点指针 并为其开辟新空间
node->data = data; //将传入的值赋给新节点
if (L->next == NULL) //判断原先链表是否为空
{
//链表为空
node->next = L->next; // 新节点next 指向NULL
node->pre = L; // 新节点pre 指向头节点
L->next = node; //头节点next 指向新节点
}
else
{
//链表不为空
node->pre = L; //新节点pre 指向头节点
node->next = L->next; //新节点next 指向头节点指向的下一个结点(首结点)
L->next->pre = node; //首结点pre 指向新节点
L->next = node; //头节点next 指向新节点
}
L->data++; //更新链表的长度 L->data 代表着记录链表的长度 加入结点 长度+1
}
3.尾插法
/尾插法
void tailInsert(Node * L,int data)
{
Node* temp = L; //借用 temp结点 来代表 头节点
Node* node = (Node*)malloc(sizeof(Node)); //开辟新空间给新节点
node->data = data; //传入的值赋给新节点
while (L->next != NULL) //找到尾结点
{
L = L->next;//将头节点指向下一结点的地址
} //结束循环 此时 L 为尾结点
node->next = L->next; //新节点next 指向 NULL
node->pre = L; //新节点pre 指向 尾结点
L->next = node; //尾结点next 指向 新节点
temp->data++; //更新链表的长度 加入链表 长度+1
}
4.删除结点
//删除结点
int deleteList(Node* L, int data)
{
Node* current = L->next; //用 current指针 代表 头节点指向的下一个结点(首结点)
while (current)
{
if (current->data == data) //找到删除的相应结点
{
current->pre->next = current->next;
//将current结点前一个结点指向current结点的下一个结点
current->next->pre = current->pre;
//将current结点后一个结点指向current结点的前一个结点
free(current); //释放current的地址
L->data--; //更新链表的长度 删除结点 长度-1
return TRUE;
}
current = current->next; //未找到 current继续指向下一个结点
}
//如果循环结束依然未找到 返回 false
return FALSE;
}
5.遍历复制链表
//遍历
void printList(Node * L)
{
Node* node = L->next; //将node 指向 首结点
while (node)
{
printf("%d->", node->data);
node = node->next; //node继续指向下一个结点
}
printf("NULL\n");
}
6.进行初始化链表
int main()
{
Node* L = intList();
headInsert(L, 1);
headInsert(L, 2);
headInsert(L, 3);
headInsert(L, 4);
tailInsert(L, 5);
tailInsert(L, 6);
tailInsert(L, 7);
tailInsert(L, 8);
printList(L);
deleteList(L, 2);
deleteList(L, 4);
deleteList(L, 6);
printList(L);
return 0;
}
7.运行结果
8.完整代码
#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
typedef struct Node
{
int data;
struct Node * next;
struct Node* pre;
}Node;
//创建空链表
Node * intList()
{
Node* L = (Node*)malloc(sizeof(Node));
L->data = 0;
L->next = NULL;
L->pre = NULL;
return L;
}
//头插法
void headInsert(Node * L,int data)
{
Node* node = (Node*)malloc(sizeof(Node));
node->data = data;
if (L->next == NULL)
{
node->next = L->next;
node->pre = L;
L->next = node;
}
else
{
node->pre = L;
node->next = L->next;
L->next->pre = node;
L->next = node;
}
L->data++;
}
//尾插法
void tailInsert(Node * L,int data)
{
Node* temp = L;
Node* node = (Node*)malloc(sizeof(Node));
node->data = data;
while (L->next != NULL)
{
L = L->next;
}
node->next = L->next;
node->pre = L;
L->next = node;
temp->data++;
}
//删除结点
int deleteList(Node* L, int data)
{
Node* current = L->next;
while (current)
{
if (current->data == data)
{
current->pre->next = current->next;
current->next->pre = current->pre;
free(current);
L->data--;
return TRUE;
}
current = current->next;
}
return FALSE;
}
//遍历
void printList(Node * L)
{
Node* node = L->next;
while (node)
{
printf("%d->", node->data);
node = node->next;
}
printf("NULL\n");
}
int main()
{
Node* L = intList();
headInsert(L, 1);
headInsert(L, 2);
headInsert(L, 3);
headInsert(L, 4);
tailInsert(L, 5);
tailInsert(L, 6);
tailInsert(L, 7);
tailInsert(L, 8);
printList(L);
deleteList(L, 2);
deleteList(L, 4);
deleteList(L, 6);
printList(L);
return 0;
}