单向,双向链表,并且实现两种链表的增加和删除功能
1. 单向链表
- 链表:线性表的链式存储,称为链表
- 逻辑结构:线性结构(一对一)
- 存储结构:链式存储(使用任意一块空间存储类型相同的数据元素)
- 逻辑相邻,物理不一定相邻
#include <stdio.h>
#include <stdlib.h>
typedef int datatype;
//创建节点结构体
typedef struct Node
{
//数据域:存储数据元素
datatype data;
//指针域:存储下一个节点的地址
struct Node *next;
}*Linklist;
Linklist create()
{
Linklist s=(Linklist)malloc(sizeof(struct Node));
if(NULL==s)
return NULL;
//成功
//s节点的数据域清0
s->data=0;
//s节点的指针域指向NULL
s->next=NULL;
return s;
}
//尾部添加
Linklist append(datatype element,Linklist head)
{
//创建新节点s
Linklist s=create_node();
if(NULL==s)
return head;
s->data=element;
//1,判断链表为空
if(NULL ==head)
{
head=s;
}
else //链表不为空
{
//1,循环到最后一个节点
Linklist p=head;
while(p->next!=NULL)
{
p=p->next;
}
//2,在p后面插入s
p->next=s;
}
return head;
}
//按位置删除
Linklist delete_by_pos(int pos,Linklist head)
{
//1,判断位置是否合法
//2,判断链表为空
if(NULL==head || pos<1 || pos>Length(head))
{
return head;
}
//3,判断是否只有一个节点,删除第一个位置
if(head->next==NULL ||pos==1)
{
head=delete_head(head);
}
else //存在多个节点 >=2
{
//找到pos-1位置的节点
Linklist p=head;
for(int i=1;i<pos-1;i++)
{
p=p->next;
}
//删除p->next
Linklist q=p->next;
p->next=q->next;
free(q);q=NULL;
}
return head;
}
//计算节点个数
int Length(Linklist head)
{
int count=0;
Linklist p=head;
while(p!=NULL)
{
count++;
p=p->next;
}
return count;
}
2. 双向链表
双向链表是在单向链表的基础上进行扩展,每个节点除了包含一个指向下一个节点的指针外,还包含一个指向前一个节点的指针。这样可以实现双向的遍历和操作。
#include <stdio.h>
#include <stdlib.h>
// 定义双向链表节点结构
typedef struct Node {
int data;
struct Node* prev;
struct Node* next;
} Node;
// 在链表末尾添加节点
void append(Node** head, int data) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->prev = NULL;
newNode->next = NULL;
if (*head == NULL) {
*head = newNode;
} else {
Node* current = *head;
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
newNode->prev = current;
}
}
// 在链表中删除指定值的节点
void delete_by_pos(Node** head, int data) {
Node* current = *head;
while (current != NULL && current->data != data) {
current = current->next;
}
if (current == NULL) {
printf("Node with data %d not found\n", data);
return;
}
if (current->prev == NULL) {
*head = current->next;
} else {
current->prev->next = current->next;
}
if (current->next != NULL) {
current->next->prev = current->prev;
}
free(current);
}