2.3 带头结点的单链表:理论+编程实战(C语言详细)
1、顺序存储:线性表/栈/队列:理论+C语言实现–详细
2.1 链式存储概述 和 2.2 线性表的链式存储–单链表(C语言详细实现)
文章目录
- 2.3 带头结点的单链表
- 1、 带头结点的单链表基本概念
- 2、ADT描述
- 3、编程实战
2.3 带头结点的单链表
1、 带头结点的单链表基本概念
单连表的缺点:
- 单链表的插入和删除操作必须对在空的单链表插入新结点、删除结点后单链表成为空表等特殊情况做特殊处理。
- 为减少对特殊情况的判断处理,可以在单链表中设置一个特殊的结点,这个结点有单链表的首指针指示,只要有这个单链表,该结点就永远不会被删除。
2、ADT描述
数据集合 K:K={k1,k2,k3…,kn},n≥0,K中的元素是datatype类型;
数据关系R:R={r} , r = {<Ki,Ki+1>|i=1,2,…,n-1};
操作集合如下:
函数 | 功能 |
---|---|
node *init() | 建立一个空的带头结点的单链表 |
void display(node *head, int i) | 输出带头结点的单链表中各个结点的值 |
node *findth(node *head, int i) | 按序号查找,在带头结点的单链表中查找第i个结点 |
node* find(node* head, datatype x) | 按值查找,在带头结点的链表中查找值为x的结点 |
node *insert(node *head , datatype x) | 在带头结点的单链表中插入一个值为x的结点 |
node *dele(node *head, datatype x) | 在带头结点的单链表中删除一个值为x的结点 |
int length(node *head) | 查询带头结点的链表的长度 |
3、重要操作
- 插入(在第i-1(1<= i <=n+1 ))个结点后插入一个值为x的新结点
- 1 先构造一个新结点,用s指向
- 2 在找到链表的第i-1个结点,用p指向
- 3 然后修改指针,插入结点(p之后插入新结点是s)
2. 删除(删除链表的第i(1<=i<=n))个位置上的结点
- 1 先找到链表的第i-1个结点,用p指向
- 2 再用指针s指向要删除的结点(p的下一个结点)
- 3 然后修改指针,删除s所指结点
- 最后释放s所指结点的空间,这样内存空间才不会泄漏
3、编程实战
头文件:head_single_linked_list.h
#pragma once #ifndef __HEAD_SINGLE_LINKED_LIST_H #define __HEAD_SINGLE_LINKED_LIST_H#include<stdio.h> #include<stdlib.h> #define error NULL typedef int datatype;typedef struct hslink_list {datatype info;struct hslink_list* next; }hs_node; //建立一个空的带头结点的单链表 hs_node* init(); //输出带头结点的单链表中各个结点的值 void display(hs_node* head); //按序号查找,在带头结点的单链表中查找第i个结点 hs_node* findth(hs_node* head, int i); //按值查找,在带头结点的链表中查找值为x的结点 int find(hs_node* head, datatype x); //在带头结点的单链表中插入一个值为x的结点 void insert(hs_node* head, datatype x, int pos); //在带头结点的单链表中删除一个值为x的结点 void dele(hs_node* head, datatype x); //查询带头结点的链表的长度 int length(hs_node* head);#endif // !__HEAD_SINGLE_LINKED_LIST_H
函数定义:head_single_linked_list.c
#include"head_single_linked_list.h" /* //带头结点的单链表初始化 参数:空 返回值:指向hs_node类型的指针 */ hs_node* init() {hs_node* head;head = (hs_node*)malloc(sizeof(hs_node));head->next = NULL;printf("链表创建成功!\n");return head; }/* 功能:输出带头结点的单链表中从头到尾各个结点的值 */ void display(hs_node* head) {hs_node* p;p = head->next;if (!p){printf("The head single linked list is empty, can not display\n");//exit(1);}else{printf("The head single linked list's value is :\n");while (p){printf("%5d", p->info);p = p->next;}printf("\n");} }hs_node* findth(hs_node* head, int i) {hs_node* p=head;int j = 0;//p = head;if (i < 0){printf("this--%d node is not exit!\n", i);}else if (i == 0) return p;else{while (p&&j!=i) //当p不为空且j小于i时,往下查找{p = p->next;j++;}return p; //如果找到则返回指向i结点的指针;否则返回指向为NULL尾结点的指针} } /* 功能:定值查找,给定一个值,找到返回其位置序号,否则返回0 */ int find(hs_node* head, datatype x) {hs_node* p;p = head->next;int i = 1;while (p!=NULL&&p->info!=x){p = p->next;i++;}if (!p){return 0;}else{return i;}} /* 功能:指定链表位置pos插入一个值为x的结点 返回:链表头结点的指针 */ void insert(hs_node* head, datatype x, int pos) {hs_node* p, * q;q=findth(head, pos);if (!q){printf("链表中不存在第%d个结点!不能插入%d", pos, x);exit(1);//return 0;}p = (hs_node*)malloc(sizeof(hs_node));p->info = x;p->next = q->next;q->next = p;printf("%3d插入成功!\n",x);//return 1; }/* 功能:删除值为x的结点*/ void dele(hs_node* head, datatype x) {hs_node* pre=head, * q;q = head->next;while (q&&q->info!=x){pre = q;q = q->next;}if (q) //当q指针不为空时,说明找到了值为x的结点{pre->next = q->next; //跳过q指向的结点free(q); //释放q指向的结点,防止内存泄漏printf("删除操作成功!\n");}else printf("删除失败!\n"); }/* 计算链表的长度(不包含头结点) */ int length(hs_node* head) {int len = 0;hs_node* p ;p = head->next;while (p){len++;p = p->next;}return len; }
main.c
#include"head_single_linked_list.h"void main() {struct hslink_list* head;head = init();int command = 0, position;while (command<5){insert(head, command, command );command++;}while (command<10){printf("input command:1:init 2:findth 3:find 4:insert 5:dele 6:length 7:display\n");scanf_s("%d", &command);switch (command){case 1:free(head); head = init(); break;case 2: {printf("请输入要查找结点的序号:\n");scanf_s("%d", &command);findth(head, command);break;}case 3: {printf("请输入要查找结点的值:\n");scanf_s("%d", &command);command=find(head, command);printf("该结点在第%d个位置\n", command);break;}case 4: {printf("请输入要查找结点的值和位置:\n");scanf_s("%d%d", &command,&position);insert(head, command, position);break;}case 5: {printf("请输入要删除结点的值:\n");scanf_s("%d", &command);dele(head, command);break;}case 6:printf("该链表不包含头结点一共有%d个结点\n", length(head)); break;case 7:display(head); break;default:printf("The command is error ,please input again!\n");break;}} }
4、程序运行结果:
2.3 带头结点的单链表:理论+编程实战(C语言详细)相关推荐
- 带头结点的单链表的操作(C语言)
初始化 先了解头结点 头结点是一个特殊的结点,它的数据域不存储信息,通常情况下,头指针指向的结点为头结点,由于头结点不存储信息,所以不是数据结构中的实际结点,第一个实际结点其实是head->ne ...
- 带头结点的单链表的逆置
代码 //带头结点的单链表逆置.cpp #include<iostream> using namespace std; struct Node{ int data; Node* next; ...
- c语言实现--不带头结点的单链表操作
1,不带头结点的单链表操作中,除了InitList(),GetElem(),ListInsert(),ListDelete()操作与带头结点的单链表有差别外,其它的操作基本上一样. 2,不带头结点单链 ...
- 对 带头结点的单链表 的操作
//带头结点的单链表 #include<iostream> using namespace std; typedef struct student { int data; ...
- 不带头结点的单链表的建立
建立该链表利用的是尾插法 // 创建一个单链表,没有头结点, #include <iostream> #include <ctime>using namespace std; ...
- 【C语言】数据结构C语言版 实验3 带头结点的单链表
slnklist.h #include <stdio.h> #include <stdlib.h> /************************************* ...
- 【C语言】数据结构C语言版 实验2 不带头结点的单链表
运行环境:Dev-C++ vs2013可能不能运行 首先新建一个头文件slnklist.h #include <stdio.h> #include <stdlib.h> /** ...
- 带头结点的单链表删除
题目:在带头结点的单链表L中,删除所有值为X的节点,并释放其空间,假设值为X的节点不唯一 分析: 和上题相似,只是多了一个头结点.另我们可以采取直接遍历的方式进行删除,设置前驱结点,当 ...
- python实现带头结点的单链表的就地逆置_6-1 带头结点的单链表就地逆置 (10 分)...
本题要求编写函数实现带头结点的单链线性表的就地逆置操作函数.L是一个带头结点的单链表,函数ListReverse_L(LinkList &L)要求在不新开辟节点的前提下将单链表中的元素进行逆置 ...
最新文章
- oracle 新建路径,Linux环境安装Oracle11g(三)——用户、路径创建及配置环境变量
- MongoDB工具最新进展
- 华为鸿蒙原生app,华为鸿蒙开发者大赛颁奖典礼临近,鸿蒙原生应用来了
- 转 点击关闭时最小化到任务栏
- 重温 2020 AI 应用场景,哪个最让你印象深刻?
- (6.0系统手机)安卓神器Xposed框架ROOT安装指南
- 人机交互大作业文档预览
- 中国工程院院士倪光南:政府应加大核心技术市场化引导
- RxJava 学习笔记(七) --- Filtering 过滤操作
- Office更新了那么多代,哪个版本好看呢?
- 巴拿赫空间上的复变函数
- 互联网金融牌照有哪些?金融牌照一览表
- matlab表达式比未知数多,matlab求解未知数
- 视觉注意力的循环神经网络模型
- 头条2019.3.16笔试题
- Python网络爬虫实战练习:爬取豆瓣图书信息
- 高级外围总线 5.0(Advanced Peripheral Bus, APB)
- 嵌入式软件研发所具备的技能
- spark运行正常,某一个Stage卡住,停止不前异常分析
- Tomcat服务器修改网站显示图标