2.1 链式存储概述 和 2.2 线性表的链式存储–单链表(C语言详细实现)
单连表的缺点:
数据集合 K:K={k1,k2,k3…,kn},n≥0,K中的元素是datatype类型;
数据关系R:R={r} , r = {
操作集合如下:
函数 | 功能 |
---|---|
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、重要操作
2. 删除(删除链表的第i(1<=i<=n))个位置上的结点
头文件:head_single_linked_list.h
#pragma once
#ifndef __HEAD_SINGLE_LINKED_LIST_H
#define __HEAD_SINGLE_LINKED_LIST_H
#include
#include
#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、程序运行结果: