1.头文件
#ifndef _LINKLIST_H_
#define _LINKLIST_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <math.h>
typedef struct DLinklist
{
int data;
struct DLinklist *next;
struct DLinklist *prev;
}*DLinklist, DNode;
#define TRAVERSE printf("TRAVERSE: %s-%d\n",traverse(head)?"SUCCESS":"NULL", __LINE__);
/*
双向链表的遍历
@param head 头指针
@return 遍历成功,返回true,否则返回false
*/
bool traverse(DLinklist head);
/*
头插法建立链表
@param head 头指针
@param data 待插入的数据
@return 创建成功,返回true,否则返回false
*/
bool insertHead(DLinklist* head, int data);
/*
尾插法建立链表
@param head 头指针
@param data 待插入的数据
@return 创建成功,返回true,否则返回false
*/
bool insertTail(DLinklist* head, int data);
/*
删除第一个节点(头节点的后一个节点)
@param head 头指针
@return 删除成功,返回true,否则返回false
*/
bool deleteHead(DLinklist* head);
/*
删除最后一个节点
@param head 头指针
@return 删除成功,返回true,否则返回false
*/
bool deleteTail(DLinklist* head);
/*
在某一位置插入节点(默认从1开始,第0个位置为链表的头结点)
@param head 链表头结点
@param data 插入数据
@param index 插入位置
@return 插入成功返回true,失败返回false
*/
bool insertByPos(DLinklist* head, int data, int pos);
/*
删除指定位置的节点(默认从1开始,第0个位置为链表的头结点)
@param head 头指针
@param pos 待删除节点的位置
@return 删除成功,返回true,否则返回false
*/
bool deleteByPos(DLinklist* head, int pos);
/*
删除指定值的节点
@param head 头指针
@param data 待删除节点的值
@param returnArr 返回删除的节点的位置
@return 删除成功,返回true,否则返回false
*/
bool deleteByValue(DLinklist* head, int data, int *returnArr);
/*
修改链表某一位置的元素值(默认从1开始,第0个位置为链表的头结点)
@param head 链表头结点
@param data 目标值
@param index 目标位置
@return 修改成功返回true,失败返回false
*/
bool updateByIndex(DLinklist* head, int data, int index);
/*
修改链表中元素值等于目标值的节点(多个相等全部修改)
@param head 链表头结点
@param data 目标值
@param newData 新值
@return 修改成功返回true,失败返回false
*/
bool updateByValue(DLinklist* head, int data, int newData);
/*
释放链表的所有节点
@param head 链表头结点
@return 释放成功返回true,失败返回false
*/
bool freeLinklist(DLinklist* head);
#endif
2.源文件
#include "DLinklist.h"
int main(int argc, char const *argv[])
{
DLinklist head = (DLinklist)malloc(sizeof(DNode));
head->data = 0;
head->next = NULL;
head->prev = NULL;
for(int i = 0; i < 10; i++)
{
//insertHead(&head, i);
insertTail(&head, i);
}
TRAVERSE;
deleteHead(&head);
TRAVERSE;
deleteTail(&head);
TRAVERSE;
deleteByPos(&head, 2);
TRAVERSE;
int *arr;
if(deleteByValue(&head, 8, arr))
{
printf("num:%d\n", arr[0]);
if(arr[0] != 0)
{
for (int i = 0; i < arr[0]; i++)
{
printf("%d ", arr[i + 1]);
}
puts("");
}
}
TRAVERSE;
insertByPos(&head, 8, 2);
TRAVERSE;
updateByIndex(&head, 8, 5);
TRAVERSE;
updateByValue(&head, 8, 6);
TRAVERSE;
printf("%d\n", freeLinklist(&head));
TRAVERSE;
return 0;
}
bool traverse(DLinklist head)
{
if(head == NULL)
return false;
else
{
int cnt = 0;
DNode* p = head;
while(p != NULL)
{
cnt++;
printf("%d ", p->data);
p = p->next;
}
printf("\n");
if(cnt - 1 == head->data)
return true;
return false;
}
}
bool insertHead(DLinklist* head, int data)
{
if((*head) == NULL)
return false;
DNode* new = (DNode *)malloc(sizeof(DNode));
if(new == NULL)
return false;
new->next = NULL;
new->prev = NULL;
new->data = data;
if((*head)->next == NULL)
{
(*head)->next = new;
new->prev = (*head);
(*head)->data++;
return true;
}
else
{
DNode* p = (*head)->next;
new->prev = (*head);
(*head)->next = new;
new->next = p;
p->prev = new;
(*head)->data++;
return true;
}
}
bool insertTail(DLinklist* head, int data)
{
if((*head) == NULL)
return false;
DNode* new = (DNode *)malloc(sizeof(DNode));
if(new == NULL)
return false;
new->next = NULL;
new->prev = NULL;
new->data = data;
DNode* p = (*head);
while(p->next != NULL)
{
p = p->next; // 遍历到尾部
}
p->next = new;
new->prev = p;
(*head)->data++;
return true;
}
bool deleteHead(DLinklist* head)
{
if((*head) == NULL)
return false;
if((*head)->next == NULL)
return true;
DNode* p = (*head)->next;
(*head)->next = p->next;
p->next->prev = (*head);
free(p); p = NULL;
(*head)->data--;
return true;
}
bool deleteTail(DLinklist* head)
{
if((*head) == NULL)
return false;
DNode* p = (*head);
while(p->next != NULL)
{
p = p->next;
}
p->prev->next = NULL;
p->prev = NULL;
free(p); p = NULL;
(*head)->data--;
return true;
}
bool deleteByPos(DLinklist* head, int pos)
{
if((*head) == NULL || (*head)->next == NULL)
return false;
if(pos < 1 || pos > (*head)->data)
return false;
DNode* p = (*head)->next;
for(int i = 1; i < pos; i++)
{
p = p->next;
}
p->prev->next = p->next;
p->next->prev = p->prev;
free(p); p = NULL;
(*head)->data--;
return true;
}
bool deleteByValue(DLinklist* head, int data, int *returnArr) {
if (*head == NULL || (*head)->next == NULL)
return false;
int pos = 1, count = 0;
DNode* p = (*head)->next;
while (p != NULL)
{
DNode* q = p->next;
if (p->data == data) {
if (p->prev) p->prev->next = q;
if (q) q->prev = p->prev;
returnArr[++count] = pos; // 存储已删除节点的位置
free(p); p = NULL;
(*head)->data--; // 更新头节点数据
}
p = q;
pos++;
}
if (count == 0)
return false;
returnArr[0] = count;
return true;
}
bool insertByPos(DLinklist* head, int data, int pos)
{
if(*head == NULL)
return false;
if(pos < 1 || pos > (*head)->data)
return false;
DNode* new = (DLinklist)malloc(sizeof(DNode));
if(new == NULL)
return false;
new->data = data;
new->next = NULL;
new->prev = NULL;
(*head)->data++;
DNode* p = (*head)->next;
for(int i = 1; i < pos - 1; i++)
{
p = p->next;
}
new->next = p->next;
p->next->prev = new;
p->next = new;
new->prev = p;
return true;
}
bool updateByIndex(DLinklist* head, int data, int index)
{
if(*head == NULL || (*head)->next == NULL)
return false;
if(index < 1 || index > (*head)->data)
return false;
DNode* p = (*head)->next;
for(int i = 1; i < index; i++)
{
p = p->next;
}
p->data = data;
return true;
}
bool updateByValue(DLinklist* head, int data, int newData)
{
if(*head == NULL || (*head)->next == NULL)
return false;
int cnt = 0;
DNode* p = (*head)->next;
while(p != NULL)
{
if(p->data == data)
{
p->data = newData;
cnt++;
}
p = p->next;
}
if(cnt == 0)
return false;
return true;
}
bool freeLinklist(DLinklist* head)
{
if((*head) == NULL)
return true;
DNode* p = (*head);
while(p != NULL)
{
DNode* q = p->next;
free(p); p = NULL;
p = q;
}
*head = NULL; // 将头指针设置为 NULL 防止悬挂指针
return true;
}