#include <stdio.h>
#include <stdlib.h>
/*
* 单链表是线性表链式存储的一种,其储存不连续。
* 单链表的数据结构中包含两个变量:数据和指向下一结点的指针。
* 一个结点只知道他的下一个结点的地址。
* 一个单链表必须有一个头指针指向该单链表中的第一个结点,否则链表会在内存中丢失。
*/
typedef int ElementData;
typedef struct node{
ElementData data;
struct node* next;
} Node, *LinkedList;
//************************************************ 函数声明列表 ************************************************
/* 1、链表初始化 得到没有头结点的空链表 */
LinkedList init();
/* 2、输出链表的内容 */
void displayList(LinkedList list);
/* 3、向链表头部插入新结点 */
LinkedList insert(LinkedList list, ElementData data);
/* 4、向链表的尾部插入新结点 */
LinkedList appendIn(LinkedList list, ElementData data);
/* 5、向链表中指定位置插入数据 */
LinkedList insertPos(LinkedList list, int pos, ElementData data);
/* 6、在查找的数据之后插入一个结点 */
LinkedList insertData(LinkedList list, ElementData find, ElementData data);
/* 7、在链表中查找指定索引位置的元素 */
LinkedList findByIndex(LinkedList list, int index);
/* 8、在链表中查找指定数据的元素的位置 */
int findByData(LinkedList list, ElementData data);
/* 9、在链表中查找指定数据的元素 */
LinkedList findByNode(LinkedList list, ElementData data);
/* 10、删除链表第一个结点 */
LinkedList removeFirst(LinkedList list);
/* 11、删除链表最后一个元素 */
LinkedList removeLast(LinkedList list);
/* 12、删除指定索引位置的结点 */
LinkedList removeByIndex(LinkedList list, int index);
/* 13、删除指定值的结点 */
LinkedList removeByData(LinkedList list, ElementData data);
/* 14、清空链表 */
LinkedList clear(LinkedList list);
//************************************************ 函数声明列表 ************************************************
/**
* 测试程序入口
*
* @return int
*/
int main() {
//初始化链表
LinkedList list = init();
displayList(list);
// 向链表头部插入数据
list = insert(list, 1);
list = insert(list, 2);
displayList(list);
// 向链表的尾部插入数据
list = appendIn(list, 3);
list = appendIn(list, 4);
list = appendIn(list, 9);
displayList(list);
// 查找指定索引位置上的元素
LinkedList found = findByIndex(list, 0);
if (found != NULL) {
printf("索引为0的元素是 %d\n", found->data);
} else {
printf("没有找到索引为0的元素\n");
}
found = findByIndex(list, 3);
if (found != NULL) {
printf("索引为3的元素是 %d\n", found->data);
} else {
printf("没有找到索引为3的元素\n");
}
// 向链表指定位置插入元素
list = insertPos(list, 2, 5);
displayList(list);
list = insertPos(list, 1, 6);
displayList(list);
list = insertPos(list, 7, 7);
displayList(list);
list = insertPos(list, 12, 25);
displayList(list);
// 按数据查找返回索引
int index = findByData(list, 2);
if (list != NULL) {
printf("保存数据 2 的结点首次出现的索引是 %d\n", index);
} else {
printf("保存数据 2 的结点没有找到\n");
}
// 安数据查找返回结点
Node *foundNode = findByNode(list, 2);
if (foundNode != NULL) {
printf("保存数据 2 的结点的下一个结点保存的数据是%d\n", foundNode->next->data);
} else {
printf("保存数据 2 的结点没有找到\n");
}
// 在查找到的数据结点后插入新数据
list = insertData(list, 5, 8);
displayList(list);
// 删除索引是0的元素
list = removeByIndex(list, 0);
displayList(list);
// 删除索引是2的元素 8
list = removeByIndex(list, 2);
printf("删除索引是2的元素后:\n");
displayList(list);
// 删除链表第一个元素
list = removeFirst(list);
displayList(list);
// 删除链表最后一个元素
list = removeLast(list);
displayList(list);
// 使用索引删除
list = removeByIndex(list, 1);
printf("删除链表中索引为 1 的结点后:\n");
displayList(list);
// 使用值搜索删除
list = removeByData(list, 2);
displayList(list);
list = removeByData(list, 3);
displayList(list);
list = removeByData(list, 7);
displayList(list);
// 清理链表
list = clear(list);
displayList(list);
return 0;
}
/**
* 链表初始化 得到没有头结点的空链表
*
* @return List
*/
LinkedList init() {
return NULL;
}
/**
* 输出链表的内容
*
* @param list
*/
void displayList(LinkedList list) {
if (list == NULL) {
printf("链表是空的!\n");
} else {
Node* cur = list;
while (cur != NULL) {
printf("%d \t", cur->data);
cur = cur->next;
}
printf("\n");
}
}
/**
* 向链表的头部插入新结点
*
* @param list
* @param data
* @return LinkedList
*/
LinkedList insert(LinkedList list, ElementData data) {
Node *tmp = (Node *) malloc(sizeof(Node));
Node *head = list;
if (tmp == NULL) {
printf("插入新结点失败\n");
return head;
} else {
tmp->data = data;
tmp->next = head;
head = tmp;
return head;
}
}
/**
* 向链表的尾部插入新结点
*
* @param list
* @param data
* @return
*/
LinkedList appendIn(LinkedList list, ElementData data) {
Node *head, *cur;
head = cur = list;
// 新结点
Node *tmp = (Node *) malloc(sizeof(Node));
tmp->data = data;
tmp->next = NULL;
// 链表为空时处理方式
if (cur == NULL) {
head = tmp;
return head;
}
// 移动指针到链表最后一个元素
while (cur->next != NULL) {
cur = cur->next;
}
cur->next = tmp;
return head;
}
/**
* 在链表中查找指定索引位置的元素
*
* @param list list
* @param index int
* @return LinkedList
*/
LinkedList findByIndex(LinkedList list, int index) {
Node *cur = list;
if (cur == NULL) {
printf("链表为空\n");
return NULL;
}
if (index < 0) {
printf("索引不能小于0");
return NULL;
}
int i = 0;
while (cur!=NULL && i < index) {
cur = cur->next;
i++;
}
return cur;
}
/**
* 在链表中查找指定数据的元素的位置(首次找到即返回)
*
* @param list LinkedList
* @param data ElementData
* @return LinkedList
*/
int findByData(LinkedList list, ElementData data) {
Node *cur = list;
if (cur == NULL) {
printf("链表为空\n");
return -1;
}
int i = 0;
while (cur != NULL) {
if (cur->data == data) {
return i;
} else {
cur = cur->next;
}
i++;
}
printf("没有找到需要的数据\n");
return -1;
}
/**
* 在链表中查找指定数据的元素的位置(首次找到即返回)
*
* @param list LinkedList
* @param data ElementData
* @return LinkedList
*/
LinkedList findByNode(LinkedList list, ElementData data) {
Node *cur = list;
if (cur == NULL) {
printf("链表为空\n");
return NULL;
}
while (cur != NULL) {
if (cur->data == data) {
return cur;
}
cur = cur->next;
}
printf("没有找到需要的数据\n");
return NULL;
}
/**
* 向链表中指定位置插入数据
*
* @param list LinkedList
* @param pos int
* @param data ElementData
* @return LinkedList
*/
LinkedList insertPos(LinkedList list, int pos, ElementData data) {
Node *head = list;
Node *cur = list;
if (cur == NULL) {
printf("链表不能为空\n");
return 0;
}
if (pos < 1) {
printf("插入位置不能小于1\n");
return 0;
}
Node *tmp = (Node *) malloc(sizeof(Node));
tmp->data = data;
if (pos == 1) {
tmp->next = cur;
head = tmp;
} else {
Node *found = findByIndex(head, (pos-1) - 1); // 插入位置的前一个元素
if (found == NULL) {
printf("指定位置超过链表长度\n");
return head;
}
tmp->next = found->next;
found->next = tmp;
}
return head;
}
/**
* 在指定的数据后面插入一个新节点
*
* @param list LinkedList
* @param find ElementData
* @param data ElementData
* @return LinkedList
*/
LinkedList insertData(LinkedList list, ElementData find, ElementData data) {
Node *head;
head = list;
if (head == NULL) {
printf("链表为空,无法进行操作\n");
return head;
}
Node *found = findByNode(head, find);
if (found == NULL) {
printf("没有找到保存数据 %d 的结点,插入失败", find);
return head;
}
// 找到后正常插入
Node *tmp = (Node *) malloc(sizeof(Node));
tmp->data = data;
tmp->next = found->next;
found->next = tmp;
return head;
}
/**
* 删除链表第一个结点
*
* @param list LinkedList
* @return LinkedList
*/
LinkedList removeFirst(LinkedList list) {
Node *head = list;
Node *tmp = NULL;
if (head == NULL) {
printf("链表为空,删除失败\n");
return head;
}
tmp = head;
head = head->next;
free(tmp);
return head;
}
/**
* 删除链表最后一个元素
*
* @param list
* @return
*/
LinkedList removeLast(LinkedList list) {
Node *head = list;
Node *cur = list;
Node *tmp = NULL;
if (cur == NULL) {
printf("链表为空,删除失败\n");
return head;
}
if (cur->next == NULL) {
tmp = cur->next;
head = tmp;
free(tmp);
return head;
}
// cur移动到指向倒数第二个结点
while (cur->next->next != NULL) {
cur = cur->next;
}
tmp = cur->next;
cur->next = NULL;
free(tmp);
return head;
}
/**
* 删除指定位置的结点
*
* @param list
* @param index
* @return
*/
LinkedList removeByIndex(LinkedList list, int index) {
Node *head = list;
Node *tmp = NULL;
if (head == NULL) {
printf("链表为空,没有元素可以删除\n");
return head;
}
if (index == 0) {
tmp = head;
head = head->next;
} else {
LinkedList found = findByIndex(head, index - 1);
if (found == NULL) {
printf("索引超过了最大可用值\n");
return head;
}
tmp = found->next;
found->next = found->next->next;
}
free(tmp);
return head;
}
/**
* 删除指定值的结点
*
* @param list
* @param data
* @return
*/
LinkedList removeByData(LinkedList list, ElementData data) {
Node *head = list;
Node *tmp = NULL;
if (head == NULL) {
printf("链表为空,没有元素可以删除\n");
return head;
}
int index = findByData(list, data);
if (index < 0) {
printf("没有找到要删除的元素\n");
return head;
} else if (index == 0) {
tmp = head;
head = head->next;
} else {
LinkedList found = findByIndex(head, index - 1);
if (found == NULL) {
printf("没有找到要查出的元素\n");
return head;
}
tmp = found->next;
found->next = found->next->next;
}
free(tmp);
return head;
}
/**
* 清空链表
*
* @param list
* @return
*/
LinkedList clear(LinkedList list) {
Node *cur = list;
int i = 1;
while (cur != NULL) {
cur = removeFirst(cur);
printf("删除第%d个元素成功\t", i);
i++;
}
printf("\n");
return NULL;
}
没有头结点的单链表[c语言实现]
最新推荐文章于 2023-03-13 14:31:14 发布