数据结构-单链表操作及代码实现(C语言)

数据结构-单链表操作及代码实现(C语言)

(一)单链表

与线性表支持随机访问的特点相比,单链表的特点是适合插入与删除。

结构体定义

typedef int ElementType; // 数据元素类型定义

typedef struct LNode // 单链表结构体定义

{

ElementType data; // 数据域

struct LNode *next; // 存储下一个结点的地址

} LNode, *LinkedList; // Lnode表示结点;LinkedList = LNode*表示链表

(二)单链表的主要操作

单链表分为带头结点和不带头结点,这里阐述使用带头结点的单链表。

1.单链表的初始化

初始化一个单链表我们首先需要创建一个新结点。

在C语言中,malloc函数可以给我们分配指定长度的内存空间。

LinkedList init_link_list()

{

LinkedList L = (LinkedList)malloc(sizeof(LNode)); // 创建头结点

L->next = NULL; // 将头结点的指针域置为NULL

return L; // 返回

}

其他内容请见下方完整代码...

完整代码如下:

#include

#include

typedef int ElementType; // 数据元素类型定义

typedef struct LNode // 单链表结构体定义

{

ElementType data; // 数据域

struct LNode *next; // 存储下一个结点的地址

} LNode, *LinkedList; // Lnode表示结点;LinkedList = LNode*表示链表

// ----------------------------------------------------------------

LinkedList init_link_list(); // 初始化含头结点的单链表

void iterate_link_list(LNode L); // 遍历单链表

void head_insert(LinkedList L, int n); // 头插法建立单链表(逆序插入)

void rear_insert(LinkedList L, int n); // 尾插法建立单链表(顺序插入)

void insert_element(LinkedList L, int i, ElementType e); // 在第i个位置插入元素e

void delete_element(LinkedList L, int i); // 删除第i个位置的元素e

int get_length(LNode L); // 计算单链表的长度

ElementType get_element(LNode L, int i); // 查找i位置的元素

int locate_element(LNode L, int value); // 查找某个元素的位置

void selection();

// ----------------------------------------------------------------

// ----------------------------------------------------------------

LinkedList init_link_list()

{

LinkedList L = (LinkedList)malloc(sizeof(LNode)); // 创建头结点

L->next = NULL; // 将头结点的指针域置为NULL

return L; // 返回

}

void iterate_link_list(LNode L)

{

LinkedList p = L.next; // p结点指向第一个元素

while (p) // 当 p->next != NULL时,进行遍历访问

{

printf("%d ", p->data); // 打印元素值

p = p->next; // p指针向后移动

}

printf("\n");

free(p); // 释放p结点

}

void head_insert(LinkedList L, int n)

{

for (int i = n; i > 0; i--)

{

LinkedList p = (LinkedList)malloc(sizeof(LNode)); // 生成新结点

scanf(" %d", &p->data); // 输入元素值

p->next = L->next; //

L->next = p; // 插入到表头

}

}

void rear_insert(LinkedList L, int n)

{

LinkedList r = L; // r结点指向头结点

for (int i = n; i > 0; i--) // 循环插入

{

LinkedList p = (LinkedList)malloc(sizeof(LNode)); // 生成新结点

scanf(" %d", &p->data); // 输入元素值

p->next = NULL; // 新结点的next指针域置为NULL

r->next = p; // 插入到表尾

r = r->next; // 表尾元素后移

}

}

void insert_element(LinkedList L, int i, ElementType e)

{

int j = 0; // 当前是第0个元素,即头结点

LinkedList p = L; // p结点指向头结点

while (p)

{

if (j == i - 1) // 找到了i-1位置

{

LinkedList temp = (LinkedList)malloc(sizeof(LNode)); // 创建新结点

temp->data = e; // 将元素e赋值给temp的数据域

temp->next = p->next; // 新插入的结点temp指向p结点的下一个结点

p->next = temp; // 将p的下一个结点指向新插入的结点temp

return;

}

j++; // j++

p = p->next; // p指针向后移动

}

}

void delete_element(LinkedList L, int i)

{

int j = 0; // 当前是第0个元素

LinkedList p = L; // p结点指向头结点

while (p && p->next) // 新加入了p->next!=NULL的判断? 为了防止删除最后一个元素时(p->next==NULL)进入循环

{

if (j == i - 1) // 找到了i-1位置

{

// 将当前结点后的元素删除

LinkedList r = p->next; // 记录p结点的下一个结点

p->next = r->next; // p->next = p->next->next

free(r); // 释放r结点

return;

}

j++; // j++

p = p->next; // p指针向后移动

}

}

int get_length(LNode L)

{

LinkedList p = L.next; // p指向第一个元素

int length = 0;

while (p) // 当p->next != NULL时

{

length++; // 长度加1

p = p->next; // p指针向后移动

}

return length; // 返回链表长度

}

ElementType get_element(LNode L, int i)

{

int j = 1; // 当前是第几个元素

LinkedList p = L.next; // p结点指向存放第一个元素的结点

while (p) // 当p->next != NULL时

{

if (j == i) // 当前位置j是否等于i位置

return p->data; // 返回元素值

j++; // j++

p = p->next; // p指针向后移动

}

exit(0); // 退出

}

int locate_element(LNode L, int value)

{

int j = 1; // 当前是第几个元素

LinkedList p = L.next; // p结点指向存放第一个元素的结点

while (p) // 当p->next != NULL时

{

if (p->data == value) // 找到了

return j; // 返回

j++; // j++

p = p->next; // p指针向后移动

}

return -1; // 未找到

}

// ----------------------------------------------------------------

void selection()

{

int option = 0; // 当前选项

LinkedList L = NULL; // 初始化

int n = 0; // 插入元素个数

int insertPosition = 0; // 插入元素的位置

int insertElement = 0; // 插入的元素

int deletePosition = 0; // 删除的元素位置

int locatePosition = 0; // 查找的第i个位置

int findElement = 0; // 查找的元素

while (1)

{

printf("========================================================================\n");

printf("\t\t 1. Init Single LinkedList. \t\t\n"); // 初始化带头结点的单链表

printf("\t\t 2. Insert Element(head insert). \t\t\n"); // 头插法建立单链表

printf("\t\t 3. Insert Element(rear insert). \t\t\n"); // 尾插法建立单链表

printf("\t\t 4. Delete element at position i. \t\t\n"); // 删除第i个位置的元素e

printf("\t\t 5. Insert an Element at position i. \t\t\n"); // 在第i个位置插入元素e

printf("\t\t 6. Find the element at position i. \t\t\n"); // 查找i位置的元素

printf("\t\t 7. Find the location of a specified element. \t\t\n"); // 查找某个指定元素的位置

printf("\t\t 8. Current length of the Single LinkedList. \t\t\n"); // 获取单链表长度

printf("\t\t 9. Print Element. \t\t\n"); // 打印元素

printf("\t\t 10. Exit. \t\t\n"); // 退出

printf("========================================================================\n");

printf("Input one number in(1-9): ");

scanf("%d", &option);

switch (option)

{

case 1:

L = init_link_list();

printf("~_~ LinkList successfully initialized.\n");

break;

case 2:

printf("Please enter the number of inserted elements(eg: 10): ");

scanf("%d", &n);

head_insert(L, n);

printf("~_~ Head Insert LinkList successfully.\n");

break;

case 3:

printf("Please enter the number of inserted elements(eg: 10): ");

scanf("%d", &n);

rear_insert(L, n);

printf("~_~ Rear Insert LinkList successfully.\n");

break;

case 4:

printf("Input delete position i (eg: 2): ");

scanf("%d", &deletePosition);

delete_element(L, deletePosition);

break;

case 5:

printf("Input insert position i (eg: 2 66): ");

scanf("%d %d", &insertPosition, &insertElement);

insert_element(L, insertPosition, insertElement);

break;

case 6:

printf("Input insert position i and element e (eg: 2): ");

scanf("%d", &locatePosition);

printf("~_~ The position [%d] element is: %d \n", locatePosition, get_element(*L, locatePosition));

break;

case 7:

printf("Input the element e (eg: 33): ");

scanf("%d", &findElement);

printf("~_~ The element [%d] position is: %d \n", findElement, locate_element(*L, findElement));

break;

case 8:

printf("~_~ Current single list length: %d\n", get_length(*L));

break;

case 9:

printf("~_~ Start Iterate LinkList.\n");

iterate_link_list(*L);

printf("~_~ Iterate LinkList successfully.\n");

break;

case 10:

printf("~_~ Exit successfully.\n");

return;

default:

printf("~_~ Please enter the correct serial number!\n ");

break;

}

}

}

int main()

{

// LinkedList L = init_link_list();

// // head_insert(L, 9); // 头插法

// rear_insert(L, 9); // 尾插法

// printf("current single list length: %d\n", get_length(*L));

// iterate_link_list(*L);

// int i = 0, element = 0;

// printf("input insert position i and element e.(eg: 2 99):");

// scanf("%d %d", &i, &element);

// insert_element(L, i, element);

// printf("current single list length: %d\n", get_length(*L));

// iterate_link_list(*L);

// delete_element(L, 3); // 删除第2个位置的元素

// printf("current single list length: %d\n", get_length(*L));

// iterate_link_list(*L);

selection();

return 0;

}

相关推荐

捕鱼炸翻天全部版本
beat365手机下载

捕鱼炸翻天全部版本

📅 01-15 👁️ 9874
淘宝如何添加旺旺子账号
365买球平台下载苹果

淘宝如何添加旺旺子账号

📅 10-01 👁️ 3733
新生儿用什么水洗澡好
365bet网投官网

新生儿用什么水洗澡好

📅 11-05 👁️ 8221
“水花消失术”背后到底有什么秘密?入水姿势物理分析
【12企中标过10亿】国家电网2024年输变电项目变电设备(728亿)中标排名数据分析
血色残阳套详细剖析 附韩服觉醒对比只针对金身
beat365手机下载

血色残阳套详细剖析 附韩服觉醒对比只针对金身

📅 07-09 👁️ 5296