/* 单链表的实现 */
/* 定义操作结果 */
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
/* 定义存储的数据类型 */
typedef int Elemtype;
/* 定义链表的结点,包括要存储的数据以及下一个结点的引用 */
typedef struct Node
{
Elemtype data;
struct Node* next;
}Node;
/* 定义链表,包括头节点和链表长度 */
typedef struct Linklist
{
Node* head;
int length;
}Linklist;
/* 初始化链表,参数是链表的指针,返回值是操作的结果(OK/ERROR) */
int initList(Linklist* list)
{
if (list == NULL)
{
return ERROR;
}
// 初始化链表,给头节点分配内存,设置头节点的数据域和指针域都为NULL,设置链表长度为0
list->head = (Node*)malloc(sizeof(Node));
if (list->head == NULL)
{
return ERROR;
}
list->head->data = -1;
list->head->next = NULL;
list->length = 0;
return OK;
}
/* 返回链表长度,参数是链表的指针,返回值是ERROR或者是链表长度 */
int length(Linklist* list)
{
if (list == NULL)
{
return ERROR;
}
return list->length;
}
/* 链表是否为空,参数是链表的指针,返回值:空表返回1,非空表返回0,错误返回-1 */
int empty(Linklist* list)
{
// 参数为NULL或者没有初始化
if ((list == NULL) || (list->head == NULL))
{
return -1;
}
// 头节点的next是第一个结点,为空则证明是空表
if (list->head->next == NULL)
{
return 1;
}
return 0;
}
/* 清空链表,参数是链表的指针,返回值是操作的结果(OK/ERROR)*/
int clear(Linklist* list)
{
// 参数为NULL或者没有初始化
if ((list == NULL) || (list->head == NULL))
{
return ERROR;
}
// 清空链表就是头节点的next为空
list->head->next = NULL;
list->length = 0;
return OK;
}
/* 查找指定位置的元素,参数是链表指针和查找的位置以及查找结果的指针,返回值是操作结果(OK/ERROR)*/
int findElem(Linklist* list, int loc, Elemtype* e)
{
Node* temp;
int index = -1;
// 参数为NULL或者没有初始化
if ((list == NULL) || (list->head == NULL))
{
return ERROR;
}
// loc小于0或者大于等于length
if ((loc < 0) || (loc >= list->length))
{
return ERROR;
}
// 遍历单链表,当前结点不为空,判断到没到指定的位置,到了跳出,没到,则继续循环
// 头结点的下一个是第一个结点
temp = list->head->next;
while (index < loc)
{
index++;// 初始值赋值为-1,在判断第一个结点的时候加1变为0
if (index == loc)
{
*e = temp->data;
return OK;
}
temp = temp->next;// 查找下一个
}
// 在上面的循环没有返回,证明没有找到
return ERROR;
}
/* 查找元素所在的位置,参数是链表的指针,要查找的数据,返回值是数据所在的位置或者-1(查找失败) */
int findLoc(Linklist* list, Elemtype e)
{
Node* temp;
int index = -1;
// 参数为NULL或者没有初始化或者数据为空
if ((list == NULL) || (list->head == NULL) || (e == -1))
{
return -1;
}
// 遍历单链表的所有元素,判断数据域是否与e相同,相同返回下标,否则继续找
temp = list->head->next;
while (temp != NULL)
{
index++;
if (temp->data == e)
{
return index;
}
temp = temp->next;
}
// 找到最后也没找到
return -1;
}
/* 插入一个数据,参数是链表的指针,要插入的位置以及要插入的元素,返回值是操作结果(OK/ERROR)*/
int insert(Linklist* list, int loc, Elemtype e)
{
Node* front;
Node* node;
int index = 0;
// 参数为NULL或者没有初始化或者数据为空
if ((list == NULL) || (list->head == NULL) || (e == -1))
{
return ERROR;
}
// loc小于0或者大于length
if ((loc < 0) || (loc > list->length))
{
return ERROR;
}
//创建新节点
node = (Node*)malloc(sizeof(Node));
if (node == NULL)
{
return ERROR;
}
node->data = e;
node->next = NULL;
// 如果是空表,直接让list的first的next是新建结点
if (empty(list))
{
list->head->next = node;
list->length++;
return OK;
}
// 不是空表,要找到插入位置的上一个位置的结点front,让node的next指向front的next,然后让front的next指向node
front = list->head;
while (index < loc)
{
front = front->next;
index++;
}
node->next = front->next;
front->next = node;
list->length++;
return OK;
}
/* 删除指定位置的结点,参数是链表的指针,要删除的位置和删除的数据指针,返回值是操作结果(OK/ERROR)*/
int del(Linklist* list, int loc, Elemtype* e)
{
Node* front;
Node* delNode;
int index = 0;
// 参数为NULL或者没有初始化
if ((list == NULL) || (list->head == NULL))
{
return ERROR;
}
// loc小于0或者大于等于length
if ((loc < 0) || (loc >= list->length))
{
return ERROR;
}
// 找到要删除结点的前一个结点front
front = list->head;
while (index < loc)
{
front = front->next;
index++;
}
// 保留被删除结点的指针,将front的next直接指向front的next的next,也就是被删结点的下一个结点
delNode = front->next;
*e = delNode->data;
front->next = delNode->next;
free(delNode);
list->length--;
return OK;
}
/* 销毁整个链表,参数是链表指针,返回值是操作结果(OK/ERROR)*/
int destroy(Linklist* list)
{
Node* temp;
Node* front;
// 参数为NULL或者没有初始化
if ((list == NULL) || (list->head == NULL))
{
return ERROR;
}
// 依次释放每一个结点的空间
temp = list->head->next;
while (temp != NULL)
{
front = temp;
temp = temp->next;
free(front);
}
// 释放头结点
free(list->head);
return OK;
}
void main()
{
Linklist list;
printf("初始化一个顺序表是否成功:%d\n", initList(&list));
printf("当前顺序表是否为空:%d\n", empty(&list));
printf("当前顺序表的长度为:%d\n", length(&list));
for (int i = 0; i < 5; i++) { //往顺序表中插入12345五个数据
printf("插入第%d个元素是否成功:%d\n", i + 1, insert(&list, i, i + 1));
}
printf("当前顺序表是否为空:%d\n", empty(&list));
printf("当前顺序表的长度为:%d\n", length(&list));
int temp;
printf("下标\t数据\n");
for (int i = 0; i < 5; i++) {
findElem(&list, i, &temp);
printf("%d\t%d\n", i, temp);
}
int d;
findElem(&list, 2, &d);
printf("第三个数据是:%d\n", d);
int index;
index = findLoc(&list, 2);
printf("2在顺序表中的下标是:%d\n", index);
int dele;
del(&list, 3, &dele);
printf("删除的下标为3的数据是:%d\n", dele);
printf("当前顺序表的长度为:%d\n", length(&list));
destroy(&list);
}
C语言实现单链表
最新推荐文章于 2024-07-25 02:49:15 发布