@


单链表

结构定义

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h> #define OK 1
#define ERROR 0
#define OVERFLOW -1
#define YES 1
#define NO 0 typedef int ElemType;
typedef int Status; #pragma warning(disable:4996) /*
单链表的存储结构定义
*/
typedef struct Node
{
ElemType data; // 数据域
struct Node* next; // 指针域
}LinkNode, * LinkList;
// *LinkList为LinkNode类型的指针
// 定义指向结点的指针: LinkNode *p 等价于 LinkList p

初始化

/*
初始化(构造一个带头结点空表)
*/
Status InitList(LinkList* L)
{
*L = (LinkNode*)malloc(sizeof(LinkNode));
(*L)->next = NULL; return OK;
}

建立

前插法

/*
单链表的建立(前插法)
*/
void CreateList_Head(LinkList L, int n)
{
ElemType e; for (int i = 0; i < n; i++) {
LinkNode* p = (LinkNode*)malloc(sizeof(LinkNode)); // 生成新结点
scanf("%d", &e);
p->data = e; // 输入元素值
p->next = L->next;
L->next = p; // 插入到表头
}
}

尾插法

/*
单链表的建立(尾插法)
*/
void CreateList_Rear(LinkList L, int n)
{
ElemType e; LinkList r = L; // 尾指针r指向头结点
for (int i = 0; i < n; i++) {
LinkNode* p = (LinkNode*)malloc(sizeof(LinkNode)); // 生成新结点
scanf("%d", &e); // 输入元素值
p->data = e;
p->next = NULL;
r->next = p; // 插入到表尾
r = p; // r指向新的尾结点
}
}

清空

/*
清空,将L重置为空表
*/
Status ClearList(LinkList L)
{
LinkNode* p;
LinkNode* q;
p = L->next; // p指向第一个结点 while (p) // 没到表尾
{
q = p->next;
free(p);
p = q;
}
L->next = NULL; // 头结点指针域为空 return OK;
}

求表长

/*
求表长,返回L中数据元素个数
*/
int GetListLength(LinkList L)
{
LinkNode* p = L->next; // p指向第一个结点
int len = 0; // 遍历单链表,统计结点数
while (p) {
len++;
p = p->next;
} return len;
}

判断是否为空表

/*
判断表是否为空
*/
Status IsListEmpty(LinkList L)
{
// 若L为空表,则返回YES,否则返回NO
if (L->next) // 非空
return NO;
else
return YES;
}

取值

/*
取值(根据位置i获取相应位置数据元素的内容,0<i<=len)
*/
Status GetElem(LinkList L, int i, ElemType* e)
{
LinkNode* p = L->next;
int j = 1; // 初始化 // 向后扫描,直到p指向第i个元素或p为空
while (p && j < i) {
p = p->next;
j++;
} if (!p || j > i) {
return ERROR; // 第i个元素不存在
} (*e) = p->data; // 若存在,取第i个元素 return OK;
}

查找

获取数据所在位置

/*
查找(根据指定数据,获取数据所在位置)
*/
LinkNode* LocateELem(LinkList L, ElemType e)
{
// 返回L中值为e的数据元素的地址,查找失败返回NULL
LinkNode* p = L->next; while (p && p->data != e) {
p = p->next;
} return p;
}

获取数据所在位序

/*
查找(根据指定元素,返回指定元素位序,0<序号<=len)
*/
int SearchElem(LinkList L, ElemType e)
{
// 返回L中值为e的数据元素的位置序号,查找失败返回0
LinkNode* p = L->next;
int j = 1; while (p && p->data != e)
{
p = p->next; j++;
} if (p) {
return j;
}
else {
return 0;
}
}

插入

/*
插入,将元素插入到指定位序(插在第 i 个结点之前,0<i<=len+1)
*/
Status InsertElem(LinkList L, int i, ElemType e)
{
LinkList p = L;
int j = 0; // 寻找第i-1个结点
while (p && j < i - 1) {
p = p->next;
j++;
} if (!p || j > i - 1) {
return ERROR; // i大于表长 + 1或者小于1
} LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode)); //生成新结点s
s->data = e; // 将结点s的数据域置为e
s->next = p->next; // 将结点s插入L中
p->next = s; return OK;
}

删除

/*
删除(删除第 i 个结点)
*/
Status DeleteElem(LinkList L, int i, ElemType* e)
{
LinkList p = L;
int j = 0; // 寻找第i个结点,并令p指向其前驱
while (p->next && j < i - 1) {
p = p->next;
j++;
} if (!(p->next) || j > i - 1) {
return ERROR; // 删除位置不合理
} LinkNode* q = p->next; // 临时保存被删结点的地址以备释放
p->next = q->next; // 改变删除结点前驱结点的指针域
(*e) = q->data; // 保存删除结点的数据域
free(q); // 释放删除结点的空间 return OK;
}

销毁

/*
销毁
*/
Status DestroyList(LinkList L)
{
LinkList p;
while (L)
{
p = L;
L = L->next;
free(p);
} return OK;
}

遍历打印

/*
遍历打印链表
*/
void PrintLinkList(LinkList L)
{
LinkNode* p = L->next; while (p)
{
printf("%d", p->data);
p = p->next;
if (p) {
printf(" ");
}
}
}

测试

int main() {
// 测试数据:1 32 80 60 44 7 9 10
LinkList L; Status a1 = InitList(&L);
printf("初始化:\na1 = %d\n", a1); printf("\n头插法:");
CreateList_Head(L, 8);
printf("链表打印:");
PrintLinkList(L); Status a2 = ClearList(L);
printf("\n\n清空链表:a2 = %d\n", a2);
printf("链表打印:");
PrintLinkList(L); printf("\n\n尾插法:");
CreateList_Rear(L, 8);
printf("链表打印:");
PrintLinkList(L); printf("\n\n求表长:");
int len1 = GetListLength(L);
printf("\nlen1 = %d\n", len1); printf("\n判断是否为空:\n");
Status a3 = IsListEmpty(L);
printf("a3 = %d\n", a3); printf("\n取值:\n");
ElemType e1;
Status a4 = GetElem(L, 9, &e1);
printf("a4 = %d, e1 = %d\n", a4, e1);
a4 = GetElem(L, 1, &e1);
printf("a4 = %d, e1 = %d\n", a4, e1);
a4 = GetElem(L, 3, &e1);
printf("a4 = %d, e1 = %d\n", a4, e1);
a4 = GetElem(L, 8, &e1);
printf("a4 = %d, e1 = %d\n", a4, e1); printf("\n查询元素地址:\n");
ElemType e2 = 1;
LinkNode* p1 = LocateELem(L, e2);
printf("p1 = %p, p1->data = %d\n", p1, p1->data);
ElemType e3 = 6;
LinkNode* p2 = LocateELem(L, e3);
printf("p2 = %p\n", p2);
ElemType e4 = 10;
LinkNode* p3 = LocateELem(L, e4);
printf("p3 = %p, p3->data = %d\n", p3, p3->data); printf("\n查询元素序号:\n");
int a5 = SearchElem(L, e2);
printf("a5 = %d\n", a5);
int a6 = SearchElem(L, e3);
printf("a6 = %d\n", a6);
int a7 = SearchElem(L, e4);
printf("a7 = %d\n", a7); printf("\n插入元素:\n");
Status a8 = InsertElem(L, 9, 99);
printf("a8 = %d\n", a8);
printf("链表打印:");
PrintLinkList(L);
a8 = InsertElem(L, 1, 11);
printf("\na8 = %d\n", a8);
printf("链表打印:");
PrintLinkList(L); printf("\n\n删除元素:\n");
ElemType e5;
Status a9 = DeleteElem(L, 3, &e5);
printf("链表打印:");
PrintLinkList(L); printf("\n\n销毁链表:");
Status a10 = DestroyList(L);
printf("\n%p", L);
printf("\n%p", L->next); return 0;
}

测试结果:

《数据结构-C语言》单链表的更多相关文章

  1. C语言单链表实现19个功能完全详解

    谢谢Lee.Kevin分享了这篇文章 最近在复习数据结构,想把数据结构里面涉及的都自己实现一下,完全是用C语言实现的. 自己编写的不是很好,大家可以参考,有错误希望帮忙指正,现在正处于编写阶段,一共将 ...

  2. js数据结构与算法--单链表的实现与应用思考

    链表是动态的数据结构,它的每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成. 现实中,有一些链表的例子. 第一个就是寻宝的游戏.你有一条线索,这条线索是指向寻找下一条线 ...

  3. 数据结构——Java实现单链表

    一.分析 单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素.链表中的数据是以结点来表示的,每个结点由元素和指针构成.在Java中,我们可以将单链表定义成一个类,单链表的基 ...

  4. PHP数据结构之实现单链表

    学习PHP中,学习完语法,开始尝试实现数据结构,今天实现单链表 <?php class node //节点的数据结构 { public $id; public $name; public $ne ...

  5. C++ 数据结构学习二(单链表)

    模板类 //LinkList.h 单链表#ifndef LINK_LIST_HXX#define LINK_LIST_HXX#include <iostream>using namespa ...

  6. C语言—单链表

    单链表操作:读取,插入和删除 #include "stdafx.h" #include <string.h> #include <stdio.h> #inc ...

  7. C语言——单链表初始化、求表长、读表元素、插入元素

    头文件Linear.h // 单链表的类型定义 typedef struct node { int data; // 数据域 struct node *next; // 指针域 }Node, *Lin ...

  8. c语言-单链表(二)

    继续复习链表知识点,本章包含单链表的增加,删除,判断是否为空,和链表长度,以及链表的排序 几个知识点 1.链表的判断是否为空 //1.判断链表是否为空 bool isempty_list(PNODE ...

  9. c语言单链表实现

    /************************************************************************* > File Name: singleLin ...

  10. C语言单链表的实现

    // //  main.c //  gfhjhgdf // //  Created by chenhao on 13-12-23. //  Copyright (c) 2013年 chenhao. A ...

随机推荐

  1. 一步步教你如何搭建K8S集群

    一.环境配置 三台CentOS7虚拟机,默认配置,内存2GB.处理器2核心. 先更新下系统 1 sudo yum update 2 sudo yum upgrade 二.安装并启动 docker 1 ...

  2. Java方法的概念以及方法的四种语法

    一.方法 方法的概念 ​ 将一个功能抽取出来,放在类中的大括号中,形成一个独立的功能,当需要使用该功能时,则调用它,这样可以增强代码的复用性(重复利用),并解决代码的冗余现象. 方法的语法: ​ [访 ...

  3. 曲线艺术编程 coding curves 第二章 三角函数曲线(TRIG CURVES)

    第二章 三角函数曲线(TRIG CURVES) 原作:Keith Peters 原文:https://www.bit-101.com/blog/2022/11/coding-curves/ 译者:池中 ...

  4. 【GIS】图层中多个面要素融合成一个面要素

            对于那些利用GIS信息进行编辑,设计的GIS专业人士来说,桌面GIS占有主导地位.GIS专业人士使用标准桌面作为工具来设计,共享,管理和发布地理信息. ArcGIS Desktop是一 ...

  5. 自然语言处理(NLP) - 前预训练时代的自监督学习

    前预训练时代的自监督学习自回归.自编码预训练的前世 神经网络(Neural Network, NN) 损失函数,度量神经网络的预测结果和真实结果相差多少 平方差损失(欧式距离角度)预测概率分部和实际标 ...

  6. element-ui Tabs 标签页刷新页面状态不丢失

    element-ui Tabs 标签页刷新页面状态不丢失 转载请表明出处 https://www.cnblogs.com/niexianda/p/14765111.html 效果 一般在使用Tabs组 ...

  7. Java NIO原理 (Selector、Channel、Buffer、零拷贝、IO多路复用)

    系列文章目录和关于我 零丶背景 最近有很多想学的,像netty的使用.原理源码,但是苦于自己对于操作系统和nio了解不多,有点无从下手,遂学习之. 一丶网络io的过程 上图粗略描述了网络io的过程,了 ...

  8. 声音克隆,精致细腻,人工智能AI打造国师“一镜到底”鬼畜视频,基于PaddleSpeech(Python3.10)

    电影<满江红>上映之后,国师的一段采访视频火了,被无数段子手恶搞做成鬼畜视频,诚然,国师的这段采访文本相当经典,他生动地描述了一个牛逼吹完,大家都信了,结果发现自己没办法完成最后放弃,随后 ...

  9. 前端自定义弹框组件、自定义弹框内容alertView popup组件

    快速实现前端自定义弹框.自定义弹框内容alertView popup组件, 请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=12491 效果图 ...

  10. 关于SQL SERVER ROW_NUMBER(),RANK(),DENSE_RANK() 的排序和分页查询问题

    经常接触SQL SERVER 的朋友来说,排序是经常遇见的问题,有的人还会傻傻自己写排序,比如用循环去写,当然这就比较难受 今天就给大家介绍一下SQL SERVER 自带的排序,共有三种,分别为ROW ...