1
0
mirror of https://github.com/Didnelpsun/CS408.git synced 2026-02-10 14:15:53 +08:00
Files
CS408/Code/Code/head/link_list.h
Didnelpsun 7f7577e4ab 更新串
2021-09-20 23:22:17 +08:00

331 lines
9.3 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 "head.h"
// 单链表结点
typedef struct LinkListNode {
element_type data;
struct LinkListNode *next;
} LinkListNode, *LinkList;
// 初始化
bool InitLinkList(LinkList &list) {
list->data = DEFAULTELEM;
list->next = nullptr;
return true;
}
LinkList InitLinkList() {
auto list = (LinkList) malloc(sizeof(LinkList));
list->data = DEFAULTELEM;
list->next = nullptr;
return list;
}
// 判空
bool EmptyLinkList(LinkList list) {
return list->next == nullptr && list->data == DEFAULTELEM;
}
// 判断链表类型
bool TypeLinkList(LinkList list) {
if (EmptyLinkList(list)) {
return NULL;
} else {
// 如果第一数据为空就代表有头节点
if (list->data == DEFAULTELEM) {
return true;
} else {
return false;
}
}
}
// 打印
bool PrintLinkList(LinkList list) {
int i = 0;
if (EmptyLinkList(list)) {
return true;
}
// 当前遍历指针
LinkListNode *node = list;
while (!TypeLinkList(list) && node != nullptr && node->data != DEFAULTELEM ||
TypeLinkList(list) && node != nullptr) {
printf("第%d个元素值为%c\n", i, node->data);
node = node->next;
i++;
}
return true;
}
// 有头节点插入
bool InsertLinkListWithHead(LinkList &list, int index, element_type elem) {
//if (!TypeLinkList(list)) {
// printf("InsertLinkListWithHead:链表不应该是无头节点类型!\n");
// return false;
//}
if (index < 1) {
printf("InsertLinkListWithHead:插入索引值%d过小\n", index);
return false;
}
// 定义一个结点指针p指向当前扫描到的结点
LinkListNode *p;
// 定义一个变量i表示当前扫描到的结点的索引号
int i = 0;
// 将链表头结点指向p为第0个结点
p = list;
// 循环遍历到达指定索引号的单链表的结点
// 条件是当前结点的下一个不为空且索引号到达,所到达的结点一定不是空结点
while (p->next != nullptr && i < index - 1) {
p = p->next;
i++;
}
// 如果此时i小于index-1表示遍历完还没有到达对应的索引
if (i < index - 1) {
printf("InsertLinkListWithHead:插入索引值过大!\n");
return false;
}
// 此时i==index-1
auto *s = (LinkListNode *) malloc(sizeof(LinkListNode));
s->data = elem;
// 将p原来的后继给新的结点
s->next = p->next;
p->next = s;
return true;
}
// 无头节点插入
bool InsertLinkListWithoutHead(LinkList &list, int index, element_type elem) {
//if (TypeLinkList(list)) {
// printf("InsertLinkListWithoutHead:链表不应该是有头节点类型!\n");
// return false;
//}
if (index < 0) {
printf("InsertLinkListWithoutHead:插入索引值%d过小\n", index);
return false;
}
auto *s = (LinkListNode *) malloc(sizeof(LinkListNode));
if (index == 0) {
s->data = elem;
// 将s的后继设为list指针
s->next = list;
// 将list指针设置为s指针
list = s;
return true;
}
// 定义一个结点指针p指向当前扫描到的结点
LinkListNode *p;
// 定义一个变量i表示当前扫描到的结点的索引号
int i = 0;
// 将链表头结点指向p为第0个结点
p = list;
// 循环遍历到达指定索引号的单链表的结点
// 条件是当前结点的下一个不为空且索引号到达,所到达的结点一定不是空结点
while (p->next != nullptr && i < index - 1) {
p = p->next;
i++;
}
// 如果此时i小于index-1表示遍历完还没有到达对应的索引
if (i < index - 1) {
printf("InsertLinkListWithoutHead:插入索引值过大!\n");
return false;
}
// 此时i==index-1
s->data = elem;
// 将p原来的后继给新的结点
s->next = p->next;
p->next = s;
return true;
}
// 后插
bool NextInsertLinkList(LinkList &list, element_type *elem, int start, int length) {
if (!TypeLinkList(list)) {
for (int i = 0; i < length; i++) {
bool result = InsertLinkListWithoutHead(list, i, elem[i + start]);
if (!result) {
printf("NextInsertLinkList:循环插入失败!索引值为%d\n", i + start);
return false;
}
}
} else {
for (int i = 0; i < length; i++) {
bool result = InsertLinkListWithHead(list, i + 1, elem[i + start]);
if (!result) {
printf("NextInsertLinkList:循环插入失败!索引值为%d\n", i + start);
return false;
}
}
}
return true;
}
// 前插
bool PriorInsertLinkList(LinkList &list, element_type *elem, int start, int length) {
if (!TypeLinkList(list)) {
for (int i = 0; i < length; i++) {
bool result = InsertLinkListWithoutHead(list, 0, elem[i + start]);
if (!result) {
printf("PriorInsertLinkList:循环插入失败!索引值为%d\n", i + start);
return false;
}
}
return true;
} else {
for (int i = 0; i < length; i++) {
bool result = InsertLinkListWithHead(list, 1, elem[i + start]);
if (!result) {
printf("PriorInsertLinkList:循环插入失败!索引值为%d\n", i + start);
return false;
}
}
return true;
}
}
// 删除
element_type *DeleteLinkListWithHead(LinkList &list, int index, int length) {
auto *elem = (element_type *) malloc(length * sizeof(element_type));
if (index < 1) {
printf("DeleteLinkListWithHead:删除索引值%d过小\n", index);
return elem;
}
if (length < 1) {
printf("DeleteLinkListWithHead:删除长度%d过小\n", length);
}
// 定义一个结点指针start指向当前扫描到的结点即要删除第一的元素的前一个
LinkListNode *start;
// 定义一个结点指针start指向当前扫描到的结点要删除最后的元素
LinkListNode *end;
// 定义一个变量i表示当前扫描到的结点的索引号
int i = 1;
// 将链表头结点的next指向start为第1个结点
start = list->next;
// 如果链表没有任何数据
if (start == nullptr) {
printf("DeleteLinkListWithHead:链表为空!\n");
return elem;
}
// 循环遍历到达指定索引号的单链表的结点
// 条件是当前结点的下一个不为空且索引号到达,所到达的结点一定不是空结点
while (start->next != nullptr && i < index - 1) {
start = start->next;
i++;
}
// 如果此时i小于index-1表示遍历完还没有到达对应的索引
if (i < index - 1) {
printf("DeleteLinkListWithHead:删除索引值%d过大\n", index);
return elem;
}
// 此时i==index-1start到达求end
end = start;
for (int i = 0; i < length; i++) {
elem[i] = end->data;
end = end->next;
if (end == nullptr) {
printf("DeleteLinkListWithHead:删除索引最大值%d大于链表最大索引%d\n", index + length - 1, length - 1);
return elem;
}
}
if (index == 1) {
list->next = end;
} else {
start->next = end->next;
}
return elem;
}
element_type *DeleteLinkListWithoutHead(LinkList &list, int index, int length) {
auto *elem = (element_type *) malloc(length * sizeof(element_type));
if (index < 0) {
printf("DeleteLinkListWithoutHead:删除索引值过小!\n");
return elem;
}
if (length < 1) {
printf("DeleteLinkListWithoutHead:删除长度%d过小\n", length);
}
// 定义一个结点指针start指向当前扫描到的结点即要删除第一的元素的前一个
LinkListNode *start;
// 定义一个结点指针start指向当前扫描到的结点要删除最后的元素
LinkListNode *end;
// i表示当前指向的是第几个结点
int i = 0;
// 将链表头结点的next指向start为第0个结点
start = list;
// 如果链表没有任何数据
if (EmptyLinkList(list)) {
printf("DeleteLinkListWithoutHead:链表为空!\n");
return elem;
}
// 循环遍历到达指定索引号的单链表的结点
// 条件是当前结点的下一个不为空且索引号到达,所到达的结点一定不是空结点
while (start->next != nullptr && i < index - 1) {
start = start->next;
i++;
}
// 如果此时i小于index-1表示遍历完还没有到达对应的索引
if (i < index - 1) {
printf("DeleteLinkListWithoutHead:删除索引值%d过大\n", index);
return elem;
}
// 到达位置
end = start;
for (int i = 0; i < length; i++) {
end = end->next;
elem[i] = end->data;
if (end->next == nullptr) {
printf("DeleteLinkListWithoutHead:删除索引最大值%d大于链表最大索引%d\n", index + length - 1, length - 1);
return elem;
}
}
// 如果删除第一个第0号结点
if (index == 0) {
start->data = end->next->data;
start->next = end->next->next;
}
start->next = end->next;
return elem;
}
// 求表长
int GetLengthLinkList(LinkList list) {
int length = 0;
LinkListNode *node = list;
while (node->next != nullptr) {
length++;
node = node->next;
}
return length;
}
// 按位查找
element_type GetLinkListElem(LinkList list, int index) {
if (index >= GetLengthLinkList(list) || index < 0) {
printf("GetLinkListElem:查找索引%d超过索引范围\n", index);
return DEFAULTELEM;
}
LinkListNode *node = list;
for (int i = 0; i < index; i++) {
node = node->next;
}
return node->data;
}
// 按值查找
int LocateLinkList(LinkList list, element_type elem) {
LinkListNode *node = list;
for (int i = 0; i < GetLengthLinkList(list); i++) {
if (node->data == elem) {
return i;
}
}
printf("LocateLinkList:未能定位到对应值%c的元素\n", elem);
return -1;
}
// 销毁
bool DestroyLinkList(LinkList &list) {
list->data = DEFAULTELEM;
delete (list);
return true;
}