1
0
mirror of https://github.com/Didnelpsun/CS408.git synced 2026-02-08 05:14:48 +08:00
Files
CS408/Code/link_list.h
2021-04-21 00:32:06 +08:00

404 lines
10 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <stdio.h>
#include <stdlib.h>
#include "head.h"
// 单链表结点
typedef struct LinkListNode {
element_type data;
struct LinkListNode* next;
} LinkListNode, *LinkList;
// 初始化有头节点单链表
int InitLinkListWithHead(LinkList list) {
list = (LinkListNode*)malloc(sizeof(LinkListNode));
if (list == NULL) {
printf("InitLinkListWithHead:初始化分配内存失败!");
return 1;
}
list->next = NULL;
return 0;
}
// 初始化无头节点单链表
int InitLinkListWithoutHead(LinkList list) {
list = NULL;
return 0;
}
// 判断有头节点单链表是否为空
int IsLinkListEmptyWithHead(LinkList list) {
if (list->next == NULL) {
return 1;
}
else {
return 0;
}
}
// 判断无头节点单链表是否为空
int IsLLinkListEmptyWithoutHead(LinkList list) {
if (list == NULL) {
return 1;
}
else {
return 0;
}
}
// 插入有头节点单链表元素
int InsertLinkListWithHead(LinkList list, int index, element_type elem) {
if (index < 1) {
printf("InsertLinkListWithHead:插入索引值过小!\n");
return 1;
}
// 定义一个结点指针p指向当前扫描到的结点
LinkListNode* p;
// 定义一个变量i表示当前扫描到的结点的索引号
int i = 0;
// 将链表头结点指向p为第0个结点
p = list;
// 循环遍历到达指定索引号的单链表的结点
// 条件是当前结点的下一个不为空且索引号到达,所到达的结点一定不是空结点
while (p->next != NULL && i < index-1) {
p = p->next;
i++;
}
// 如果此时i小于index-1表示遍历完还没有到达对应的索引
if (i < index-1) {
printf("InsertLinkListWithHead:插入索引值过大!\n");
return 1;
}
// 此时i==index-1
LinkListNode* s = (LinkListNode*)malloc(sizeof(LinkListNode));
if (s == NULL) {
printf("InsertLinkListWithHead:分配内存失败!\n");
return 1;
}
s->data = elem;
// 将p原来的后继给新的结点
s->next = p->next;
p->next = s;
return 0;
}
// 插入无头节点单链表元素
int InsertLinkListWithoutHead(LinkList list, int index, element_type elem) {
if (index < 0) {
printf("InsertLinkListWithoutHead:插入索引值过小!\n");
return 1;
}
if (index == 0) {
LinkListNode* s = (LinkListNode*)malloc(sizeof(LinkListNode));
if (s == NULL) {
printf("InsertLinkListWithoutHead:分配内存失败!\n");
return 1;
}
s->data = elem;
// 将s的后继设为list指针
s->next = list;
// 将list指针设置为s指针
list = s;
return 0;
}
// 定义一个结点指针p指向当前扫描到的结点
LinkListNode* p;
// 定义一个变量i表示当前扫描到的结点的索引号
int i = 0;
// 将链表头结点指向p为第0个结点
p = list;
// 循环遍历到达指定索引号的单链表的结点
// 条件是当前结点的下一个不为空且索引号到达,所到达的结点一定不是空结点
while (p->next != NULL && i < index - 1) {
p = p->next;
i++;
}
// 如果此时i小于index-1表示遍历完还没有到达对应的索引
if (i < index - 1) {
printf("InsertLinkListWithoutHead:插入索引值过大!\n");
return 1;
}
// 此时i==index-1
LinkListNode* s = (LinkListNode*)malloc(sizeof(LinkListNode));
s->data = elem;
// 将p原来的后继给新的结点
s->next = p->next;
p->next = s;
return 0;
}
// 后插入单链表元素
int InsertNextLinkListNode(LinkListNode* node, element_type elem) {
if (node == NULL) {
printf("InsertNextLinkListNode:插入结点为空!");
return 1;
}
LinkListNode* s = (LinkListNode*)malloc(sizeof(LinkListNode));
// 如果分配空间失败
if (s == NULL) {
printf("InsertNextLinkListNode:分配内存失败!\n");
return 1;
}
s->data = elem;
s->next = node->next;
node->next = s;
return 0;
}
// 前插入单链表元素
int InsertPriorLinkListNode(LinkListNode* node, element_type elem) {
if (node == NULL) {
printf("InsertPriorLinkListNode:插入结点为空!");
return 1;
}
LinkListNode* s = (LinkListNode*)malloc(sizeof(LinkListNode));
// 如果分配空间失败
if (s == NULL) {
printf("InsertPriorLinkListNode:分配内存失败!\n");
return 1;
}
s->next = node->next;
node->next = s;
s->data = node->data;
node->data = elem;
return 0;
}
// 删除有头节点单链表元素
int DeleteLinkListWithHead(LinkList list, int index, element_type *elem) {
if (index < 1) {
printf("DeleteLinkListWithHead:删除索引值过小!\n");
return 1;
}
// p指向当前扫描的结点
LinkListNode* p;
// i表示当前指向的是第几个结点
int i = 0;
// 指向头结点
p = list;
while (p != NULL && i < index - 1) {
p = p->next;
i++;
}
if (p == NULL || p->next == NULL) {
printf("DeleteLinkListWithHead:删除索引值过大!\n");
return 1;
}
// q指向被删除的结点
LinkListNode* q = p->next;
// 获取删除的元素数据
*elem = q->data;
// 将q结点从链表中断开
p->next = q->next;
free(q);
return 0;
}
// 删除无头节点单链表元素
int DeleteLinkListWithHead(LinkList list, int index, element_type* elem) {
if (index < 0) {
printf("DeleteLinkListWithHead:删除索引值过小!\n");
return 1;
}
// p指向当前扫描的结点
LinkListNode* p;
// i表示当前指向的是第几个结点
int i = 0;
// 指向头结点
p = list;
// 如果删除第一个第0号结点
if (index == 0) {
list = p->next;
free(p);
return 0;
}
while (p != NULL && i < index - 1) {
p = p->next;
i++;
}
if (p == NULL || p->next == NULL) {
printf("DeleteLinkListWithHead:删除索引值过大!\n");
return 1;
}
// q指向被删除的结点
LinkListNode* q = p->next;
// 获取删除的元素数据
*elem = q->data;
// 将q结点从链表中断开
p->next = q->next;
free(q);
return 0;
}
// 删除单链表元素
int DeleteLinkListNode(LinkListNode* node) {
if (node == NULL) {
printf("DeleteLinkListNode:本结点是空结点无法删除!");
return 1;
}
// 如果该结点为最后一个结点,无法找到前驱结点,无法操作
if (node->next = NULL) {
printf("DeleteLinkListNode:后继结点为空无法操作!");
return 1;
}
// 指向后继结点
LinkListNode* p = node->next;
// 交换数据
node->data = p->data;
// 断开结点
node->next = p->next;
free(p);
return 0;
}
// 按位查找单链表元素
element_type GetLinkListElement(LinkList list, int index) {
if (index < 0) {
printf("GetLinkListElement:查找索引值过小!\n");
return NULL;
}
// 定义一个结点指针p指向当前扫描到的结点
LinkListNode* p;
// 定义一个变量i表示当前扫描到的结点的索引号
int i = 0;
// 将链表头结点指向p为第0个结点
p = list;
// 循环遍历到达指定索引号的单链表的结点
// 条件是当前结点的下一个不为空且索引号到达,所到达的结点一定不是空结点
while (p->next != NULL && i < index) {
p = p->next;
i++;
}
// 如果查找索引大于当前扫描索引
if (i < index) {
printf("GetLinkListElement:查找索引值过大!\n");
return NULL;
}
return p->data;
}
// 按位查找单链表结点
LinkListNode* GetLinkListNode(LinkList list, int index) {
if (index < 0) {
printf("GetLinkListNode:查找索引值过小!\n");
return NULL;
}
// 定义一个结点指针p指向当前扫描到的结点
LinkListNode* p;
// 定义一个变量i表示当前扫描到的结点的索引号
int i = 0;
// 将链表头结点指向p为第0个结点
p = list;
// 循环遍历到达指定索引号的单链表的结点
// 条件是当前结点的下一个不为空且索引号到达,所到达的结点一定不是空结点
while (p->next != NULL && i < index) {
p = p->next;
i++;
}
// 如果查找索引大于当前扫描索引
if (i < index) {
printf("GetLinkListNode:查找索引值过大!\n");
}
// 如果索引值过大其p也会指向最后一个NULL所以返回值都是一样为NULL不需要单独处理
return p;
}
// 按值查找单链表结点
LinkListNode* LocateLinkListNode(LinkList list, element_type elem) {
LinkListNode* p = list;
while (p != NULL && p->data != elem) {
p = p->next;
}
return p;
}
// 求链表长度
int GetLength(LinkList list) {
int len = 0;
LinkListNode* p = list;
while (p->next != NULL) {
p = p->next;
len++;
}
return len;
}
// 后插建立带头节点单链表
LinkList TailBuildLinkListWithHead(LinkList list, int length) {
element_type elem;
list = (LinkList)malloc(sizeof(LinkListNode));
// s指针为一个中间变量指针r指针为尾指针next指向最后一个元素
LinkListNode* s, * r = list;
int i = 0;
element_type x;
if (length < 1) {
printf("TailBuildLinkListWithHead:输入的单链表长度过小!");
return 1;
}
while (i < length) {
scanf("%d", &x);
s = (LinkListNode*)malloc(sizeof(LinkListNode));
s->data = x;
r->next = s;
r = s;
i++;
}
r->next = NULL;
return list;
}
// 前插建立带头节点单链表
LinkList HeadBuildLinkListWithHead(LinkList list, int length) {
element_type elem;
list = (LinkList)malloc(sizeof(LinkListNode));
// 将单链表尾部设置为NULL
list->next = NULL;
// s指针为一个中间变量指针
LinkListNode* s;
int i = 0;
element_type x;
if (length < 1) {
printf("HeadBuildLinkListWithHead:输入的单链表长度过小!");
return 1;
}
while (i < length) {
scanf("%d", &x);
s = (LinkListNode*)malloc(sizeof(LinkListNode));
s->data = x;
s->next = list->next;
list->next = s;
i++;
}
return list;
}
// 初始化有头节点循环单链表
int InitCircularLinkListWithHead(LinkList list) {
list = (LinkListNode*)malloc(sizeof(LinkListNode));
if (list == NULL) {
printf("InitCircularLinkListWithHead:初始化分配内存失败!");
return 1;
}
list->next = list;
return 0;
}
// 判断有头节点循环单链表是否为空
int IsCircularLinkListEmptyWithHead(LinkList list) {
if (list->next == list) {
return 1;
}
else {
return 0;
}
}
// 判断结点是否尾有头节点循环单链表的尾结点
int IsCircularLinkListEndWithHead(LinkList list, LinkListNode* node) {
if (node->next == list) {
return 1;
}
else {
return 0;
}
}