1.头文件
#ifndef __LINKLIST_H__
#define __LINKLIST_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <math.h>
#define TRAVERSE printf("traverse: %s-%d\n", traverse(head)?"SUCCESS":"FAIL", __LINE__) // 遍历,输出行号
typedef struct linklist
{
int data;
struct linklist* next;
}*Linklist, LNode;
/*
链表的遍历
@param head 链表头结点
@return 遍历成功返回true,失败返回false
*/
bool traverse(Linklist head);
/*
带头结点的链表头插
@param head 链表头结点
@param data 插入数据
@return 插入成功返回true,失败返回false
*/
bool insertHead(Linklist* head, int data);
/*
带头结点的链表尾插
@param head 链表头结点
@param data 插入数据
@return 插入成功返回true,失败返回false
*/
bool insertTail(Linklist* head, int data);
/*
带头结点的链表头删(删除第一个节点)
@param head 链表头结点
@return 删除成功返回true,失败返回false
*/
bool deleteHead(Linklist* head);
/*
带头结点的链表尾删(删除最后一个节点)
@param head 链表头结点
@return 删除成功返回true,失败返回false
*/
bool deleteTail(Linklist* head);
/*
在某一位置插入节点(默认从1开始,第0个位置为链表的头结点)
@param head 链表头结点
@param data 插入数据
@param index 插入位置
@return 插入成功返回true,失败返回false
*/
bool insertByIndex(Linklist* head, int data, int index);
/*
删除某一位置的节点(默认从1开始,第0个位置为链表的头结点)
@param head 链表头结点
@param index 删除位置
@return 删除成功返回true,失败返回false
*/
bool deleteByIndex(Linklist* head, int index);
/*
删除某一值等于目标值的节点(多个相等全部删除)
@param head 链表头结点
@param data 目标值
@param returnArr 数组的指针,存储下标个数,以及下标值
@return 删除成功返回true,失败返回false
*/
bool deleteByValue(Linklist* head, int data, int *returnArr);
/*
修改链表某一位置的元素值(默认从1开始,第0个位置为链表的头结点)
@param head 链表头结点
@param data 目标值
@param index 目标位置
@return 修改成功返回true,失败返回false
*/
bool updateByIndex(Linklist* head, int data, int index);
/*
修改链表中元素值等于目标值的节点(多个相等全部修改)
@param head 链表头结点
@param data 目标值
@param newData 新值
@return 修改成功返回true,失败返回false
*/
bool updateByValue(Linklist* head, int data, int newData);
/*
链表的逆置
@param head 链表头结点
@return 逆置成功返回true,失败返回false
*/
bool reverse(Linklist* head);
/*
链表的排序
@param head 链表头结点
@param mode 排序方式,0为升序,1为降序
@return 排序成功返回true,失败返回false
*/
bool sort(Linklist head, int mode);
/*
查找链表倒数第n个节点
@param head 链表头结点
@param n 倒数第n个节点
@return 查找成功返回节点数据域的值,失败返回-1
*/
int findLastN(Linklist head, int n);
/*
释放链表的所有节点
@param head 链表头结点
@return 释放成功返回true,失败返回false
*/
bool freeLinklist(Linklist* head);
#endif
2.源文件
#include "linklist.h"
int main(int argc, char const *argv[])
{
Linklist head = (Linklist)malloc(sizeof(LNode)); // 创建头节点
head->data = 0;
head->next = NULL;
for(int i = 0; i < 10; i++)
{
insertTail(&head, i);
}
TRAVERSE;
// printf("deleteHead: %s-%d\n", deleteHead(&head)?"SUCCESS":"FAIL", __LINE__);
// TRAVERSE;
// printf("deleteTail: %s-%d\n", deleteTail(&head)?"SUCCESS":"FAIL", __LINE__);
// TRAVERSE;
// printf("insertByIndex: %s-%d\n", insertByIndex(&head, 4, 2)?"SUCCESS":"FAIL", __LINE__);
// TRAVERSE;
// printf("deleteByIndex: %s-%d\n", deleteByIndex(&head, 2)?"SUCCESS":"FAIL", __LINE__);
// TRAVERSE;
// int *arr;
// deleteByValue(&head, 0, arr);
// printf("num:%d\n", arr[0]);
// for (int i = 0; i < arr[0]; i++)
// {
// printf("%d ", arr[i + 1]);
// }
// puts("");
// TRAVERSE;
// updateByIndex(&head, 3, 3);
// TRAVERSE;
// updateByValue(&head, 3, 9);
// TRAVERSE;
// reverse(&head);
// TRAVERSE;
// sort(head, 1);
// TRAVERSE;
//printf("%d\n", findLastN(head, 1));
freeLinklist(&head);
TRAVERSE;
return 0;
}
bool traverse(Linklist head)
{
if(head == NULL)
return false;
int cnt = 0;
LNode* p = head;
while (p)
{
printf("%d ", p->data);
p = p->next;
cnt++;
}
puts("");
if(cnt - 1 == head->data)
return true;
else
return false;
}
bool insertHead(Linklist* head, int data)
{
if((*head) == NULL)
return false;
LNode* newNode = (Linklist)malloc(sizeof(LNode));
if(newNode == NULL)
return false;
newNode->data = data;
newNode->next = NULL;
newNode->next = (*head)->next;
(*head)->next = newNode;
(*head)->data++;
return true;
}
bool insertTail(Linklist* head, int data)
{
if((*head) == NULL)
return false;
LNode* newNode = (Linklist)malloc(sizeof(LNode));
if(newNode == NULL)
return false;
newNode->data = data;
newNode->next = NULL;
(*head)->data++;
LNode* t = *head;
while (t->next) { t = t->next;} // 找到尾节点
t->next = newNode;
return true;
}
bool deleteHead(Linklist* head)
{
if((*head)->next == NULL)
return false;
LNode* p = (*head)->next;
(*head)->next = p->next;
(*head)->data--;
free(p); p = NULL;
return true;
}
bool deleteTail(Linklist* head)
{
if((*head)->next == NULL)
return false;
LNode* p = *head;
while(p->next->next) {p = p->next;}
LNode* q = p->next;
free(q); q = NULL;
p->next = NULL;
(*head)->data--;
return true;
}
bool insertByIndex(Linklist* head, int data, int index)
{
if(index < 1 || index > (*head)->data)
return false;
LNode* newNode = (Linklist)malloc(sizeof(LNode));
newNode->data = data;
newNode->next = NULL;
LNode* p = *head;
for(int i = 0; i < index - 1; i++)
{
p = p->next; // 找到插入位置的前一个节点
}
newNode->next = p->next;
p->next = newNode;
(*head)->data++;
return true;
}
bool deleteByIndex(Linklist* head, int index)
{
if(index < 1 || index > (*head)->data)
return false;
LNode* p = *head;
for(int i = 0; i < index - 1; i++)
{
p = p->next; // 找到删除位置的前一个节点
}
LNode* q = p->next;
p->next = q->next;
free(q); q = NULL;
(*head)->data--;
return true;
}
bool deleteByValue(Linklist* head, int data, int *returnArr)
{
if((*head)->next == NULL)
return false;
int count = 0;
LNode* p = (*head)->next;
LNode* prev = *head;
int index = 1;
while (p != NULL)
{
if (p->data == data)
{
returnArr[++count] = index;
prev->next = p->next;
free(p);
p = prev->next;
(*head)->data--;
}
else
{
prev = p;
p = p->next;
}
index++;
}
if(count == 0)
return false;
returnArr[0] = count;
return true;
}
bool updateByIndex(Linklist* head, int data, int index)
{
if(index < 1 || index > (*head)->data)
return false;
LNode* p = *head;
for(int i = 0; i < index; i++)
{
p = p->next; // 找到修改的节点
}
p->data = data;
return true;
}
bool updateByValue(Linklist* head, int data, int newData)
{
if((*head)->next == NULL)
return false;
LNode* p = (*head)->next;
while (p != NULL)
{
if (p->data == data)
{
p->data = newData;
}
p = p->next;
}
return true;
}
bool reverse(Linklist* head)
{
if((*head)->next == NULL)
return false;
if((*head)->data == 1)
return true;
Linklist current = (*head)->next->next;
(*head)->next->next = NULL;
while(current != NULL){
Linklist p = current;
current = current->next;
p->next = (*head)->next;
(*head)->next = p;
}
return true;
}
bool sort(Linklist head, int mode)
{
if(head->next == NULL)
return false;
if(mode == 0)
{
for(int i = 0; i < head->data - 1; i++)
{
Linklist current = head->next;
while(current->next != NULL)
{
if(current->data > current->next->data)
{
int temp = current->data;
current->data = current->next->data;
current->next->data = temp;
}
current = current->next;
}
}
}
else if(mode == 1)
{
for(int i = 0; i < head->data - 1; i++)
{
Linklist current = head->next;
while(current->next != NULL)
{
if(current->data < current->next->data)
{
int temp = current->data;
current->data = current->next->data;
current->next->data = temp;
}
current = current->next;
}
}
}
return true;
}
int findLastN(Linklist head, int n)
{
if(head->next == NULL)
return -1;
if(n > head->data || n < 1)
return -1;
LNode* q = head->next;
LNode* p = head->next;
for(int i = 0; i < n; i++)
{
p = p->next;
}
while(p != NULL)
{
q = q->next;
p = p->next;
}
return q->data;
}
bool freeLinklist(Linklist* head)
{
if((*head) == NULL)
return true;
LNode* p = (*head);
while(p != NULL)
{
LNode* q = p->next;
free(p); p = NULL;
p = q;
}
*head = NULL; // 将头指针设置为 NULL 防止悬挂指针
return true;
}
(PS:链表为带头结点的单链表)