静态链表的基础操作(详解)

2023-11-09

一、闵版

1.完整代码

#include <stdio.h>
#include <malloc.h>
#include <iostream>

using namespace std;

#define DEFAULT_SIZE 5

typedef struct StaticLinkedNode
{
	char data;
	int next;	
}*NodePtr;

typedef struct StaticLinkedList
{
	NodePtr nodes;
	int* used;
}*ListPtr;

ListPtr initLinkedList()
{
	
	ListPtr tempPtr = (ListPtr)malloc(sizeof(struct StaticLinkedNode));
	
	tempPtr->nodes = (NodePtr)malloc(sizeof(struct StaticLinkedNode) * DEFAULT_SIZE);//nodes就是一个数组
	tempPtr->used = (int*)malloc(sizeof(int) * DEFAULT_SIZE);//used是一个表示是否被占用的数组

	tempPtr->nodes[0].data = '\0';
	tempPtr->nodes[0].next = -1;//NULL

	// Only the first node is used.
	tempPtr->used[0] = 1;

	for(int i = 1;i<DEFAULT_SIZE;i++)
	{
		tempPtr->used[i] = 0;
	}

	return tempPtr;
}

/*打印静态链表*/
void printList(ListPtr paraListPtr)
{
	int p = 0;

	while(p!=-1)
	{
		cout<<paraListPtr->nodes[p].data<<" ";	
		p = paraListPtr->nodes[p].next;
	}

	cout<<endl<<endl;
}

/*任意位置插入结点*/
void insertElement(ListPtr paraListPtr, char paraChar, int paraPosition)
{
	int p,q,i;

	// Step 1. Search to the position.
	p = 0;

	for(i = 0;i < paraPosition;i++)
	{
		p = paraListPtr->nodes[p].next;

		if(p == -1)
		{
			printf("The position %d is beyond the scope of the list.\r\n", paraPosition);
			return;
		}
	}

	// Step 2. Construct a new node.
	for(i = 1;i<DEFAULT_SIZE; i ++)
	{
		if(paraListPtr->used[i] == 0)//找到没有运用的空间
		{
			cout<<"Space at "<<i<<" allocated"<<endl<<endl;
			paraListPtr->used[i] = 1;
			q = i;
			break;
		}
	}

	if(i == DEFAULT_SIZE)
	{
		cout<<"No Space"<<endl<<endl;
		return;
	}

	paraListPtr->nodes[q].data = paraChar;

	cout<<"Linking.....\n"<<endl;

	paraListPtr->nodes[q].next = paraListPtr->nodes[p].next;
	paraListPtr->nodes[p].next = q;
}

/*删除结点*/
void deleteElement(ListPtr paraListPtr, char paraChar)
{
	int p,q;

	p=0;

	while((paraListPtr->nodes[p].next != -1) && (paraListPtr->nodes[paraListPtr->nodes[p].next].data != paraChar))//本结点next指针域所指向的下一
																												 //个结点的数据域
	{
		p = paraListPtr->nodes[p].next;
	}//循环结束,p是目标结点的上一个结点的指针域指向数据域为paraChar的结点

	if(paraListPtr->nodes[p].next == -1)//p走到最后一位的下一个,即先想去看空结点的时候,还没有找到数据域为paraChar的结点。表明没有该结点
	{
		cout<<paraChar<<"Cannot Find!"<<endl;
		return;
	}

	q = paraListPtr->nodes[p].next;//记录目标结点的下标,q指向目标结点
	paraListPtr->nodes[p].next = paraListPtr->nodes[q].next;//使目标结点的上一个结点指向目标结点的下一个结点

	// This statement is identical to free(q)
	paraListPtr->used[q] = 0;

}

void Test()
{
	ListPtr tempList = initLinkedList();

	insertElement(tempList, 'H', 0);
	insertElement(tempList, 'e', 1);
	insertElement(tempList, 'l', 2);
	insertElement(tempList, 'l', 3);
	insertElement(tempList, 'o', 4);
	printList(tempList);

	printf("Deleting 'e'.\r\n");
	deleteElement(tempList, 'e');
	printf("Deleting 'a'.\r\n");
	deleteElement(tempList, 'a');
	printf("Deleting 'o'.\r\n");
	deleteElement(tempList, 'o');
	printList(tempList);

	insertElement(tempList, 'x', 1);
	printList(tempList);

}

int main()
{
	Test();

	system("pause");
	return 0;
}

2.运行结果

在这里插入图片描述

二、钦版

1.结构体的创建

typedef struct _StatickLinkNode
{
	int data;
	int next;
}StackLinkNode;

typedef struct _StatickLink
{
	StackLinkNode *Data;
	int *used;
}StaticLink,*StatickLinkPtr;

2.静态链表的初始化

bool initStaticLink(StatickLinkPtr &L)
{

	L = new StaticLink;
	L->Data = new StackLinkNode[MaxSize];
	L->used = new int[MaxSize];

	if(!L||!L->Data||!L->used)
		return false;

	L->Data[0].data = 0;
	L->Data[0].next = null;
	L->used[0] = 1;

	for(int i=1;i<MaxSize;i++)
	{
		L->used[i] = 0;
	}

	return true;
}

在这里插入图片描述

3.尾插法

void InsertByTail(StatickLinkPtr &L,int e)
{
	int pos = 0,i,q = 1,r=0;

	//查找最后一个结点
	while(pos != -1)
	{
		r = pos;//r记录尾结点的下标
		pos = L->Data[r].next;
	}//pos = 3
	
	for(i = 1;i<MaxSize;i++)
	{
		if(L->used[i] == 0)
		{
			cout<<endl<<"找到空闲空间:"<<i<<endl;
			L->used[i] = 1; 
			q = i;
			break;
		}
	}

	if(pos>=MaxSize || i>=MaxSize)
	{
		cout<<"无法在尾部插入!!"<<endl;
		return;
	}

	L->Data[q].data = e;//新的尾结点的数据域存放新的数据
	L->Data[q].next = null;//指针域为-1,成为新的尾结点
	L->Data[r].next = q; // 原来的尾结点的指针域,指向新的尾结点

}

在这里插入图片描述

4.按值插入

void insertElementByData(StatickLinkPtr &L,int e,int element)// 新元素值  目标结点的元素值
{
	int pos = 0,i,q,last=0;

	for(i = 1;i<MaxSize;i++)
	{
		if(L->used[i] == 0)
		{
			cout<<endl<<"找到空闲空间:"<<i<<endl;
			L->used[i] = 1; 
			q = i;
			break;
		}
	}

	while(L->Data[pos].data!= element)
	{
		last = pos;
		pos = L->Data[pos].next;
	}//pos = 5, last = 1

	L->Data[last].next = q;
	L->Data[q].next = pos;
	L->Data[q].data = e;
}

在这里插入图片描述

操作如下:
在这里插入图片描述

5.删除元素

void deleteElement(StatickLinkPtr &L,int e)
{
	int pos = 0,q;

	while((L->Data[pos].data != null) && (L->Data[L->Data[pos].next].data != e))
	{
		pos = L->Data[pos].next;
	}//pos是目标节点的上一个结点的指针域,即目标结点的下标

	q = L->Data[pos].next;//目标结点的下标

	L->Data[pos].next = L->Data[L->Data[pos].next].next;//目标结点的下一个结点的下标 由 目标结点的上一个结点的指针域指向

	L->used[q] = 0;
}

删除元素3:
在这里插入图片描述

6.打印静态链表

void PrintStaticLink(StatickLinkPtr &L)
{
	int pos = 0;

	cout<<endl<<"静态链表打印:"<<endl;
	while(pos != -1)
	{
		cout<<L->Data[pos].data<<" ";
		pos = L->Data[pos].next;
	}
	cout<<endl;
}

7.摧毁链表

bool DestroyStaticlinkList(StatickLinkPtr &L)
{
	if(!L)
		return false;
	int pos = 0;

	for(int i = 0;i<MaxSize;i++)
	{
		L->used[i] = 0;
	}

	return true;
}

8.完整代码

#include <iostream>

using namespace std;

#define null -1
#define MaxSize 8

typedef struct _StatickLinkNode
{
	int data;
	int next;
}StackLinkNode;

typedef struct _StatickLink
{
	StackLinkNode *Data;
	int *used;
}StaticLink,*StatickLinkPtr;

bool initStaticLink(StatickLinkPtr &L)
{

	L = new StaticLink;
	L->Data = new StackLinkNode[MaxSize];
	L->used = new int[MaxSize];

	if(!L||!L->Data||!L->used)
		return false;

	L->Data[0].data = 0;
	L->Data[0].next = null;
	L->used[0] = 1;

	for(int i=1;i<MaxSize;i++)
	{
		L->used[i] = 0;
	}

	return true;
}


void InsertByTail(StatickLinkPtr &L,int e)
{
	int pos = 0,i,q = 1,r=0;

	//查找最后一个结点
	while(pos != -1)
	{
		r = pos;//r记录尾结点的下标
		pos = L->Data[r].next;
	}//pos = 3
	
	for(i = 1;i<MaxSize;i++)
	{
		if(L->used[i] == 0)
		{
			cout<<endl<<"找到空闲空间:"<<i<<endl;
			L->used[i] = 1; 
			q = i;
			break;
		}
	}

	if(pos>=MaxSize || i>=MaxSize)
	{
		cout<<"无法在尾部插入!!"<<endl;
		return;
	}

	L->Data[q].data = e;//新的尾结点的数据域存放新的数据
	L->Data[q].next = null;//指针域为-1,成为新的尾结点
	L->Data[r].next = q; // 原来的尾结点的指针域,指向新的尾结点

}

void insertElementByData(StatickLinkPtr &L,int e,int element)// 新元素值  目标结点的元素值
{
	int pos = 0,i,q,last=0;

	for(i = 1;i<MaxSize;i++)
	{
		if(L->used[i] == 0)
		{
			cout<<endl<<"找到空闲空间:"<<i<<endl;
			L->used[i] = 1; 
			q = i;
			break;
		}
	}

	while(L->Data[pos].data!= element)
	{
		last = pos;
		pos = L->Data[pos].next;
	}//pos = 5, last = 1

	L->Data[last].next = q;
	L->Data[q].next = pos;
	L->Data[q].data = e;
}
void deleteElement(StatickLinkPtr &L,int e)
{
	int pos = 0,q;

	while((L->Data[pos].data != null) && (L->Data[L->Data[pos].next].data != e))
	{
		pos = L->Data[pos].next;
	}//pos是目标节点的上一个结点的指针域,即目标结点的下标

	q = L->Data[pos].next;//目标结点的下标

	L->Data[pos].next = L->Data[L->Data[pos].next].next;//目标结点的下一个结点的下标 由 目标结点的上一个结点的指针域指向

	L->used[q] = 0;
}

void PrintStaticLink(StatickLinkPtr &L)
{
	int pos = 0;

	cout<<endl<<"静态链表打印:"<<endl;
	while(pos != -1)
	{
		cout<<L->Data[pos].data<<" ";
		pos = L->Data[pos].next;
	}
	cout<<endl;
}



bool DestroyStaticlinkList(StatickLinkPtr &L)
{
	if(!L)
		return false;
	int pos = 0;

	for(int i = 0;i<MaxSize;i++)
	{
		L->used[i] = 0;
	}

	return true;
}

void Test()
{
	StatickLinkPtr L = NULL;
	StatickLinkPtr s = NULL;
	//1.初始化
	if(initStaticLink(L))
		cout<<"初始化成功!!!"<<endl;
	else
		cout<<"初始化失败!!!"<<endl;

	//2.尾插法
	int num = 0;
	cout<<"请输入尾部插的次数:";
	cin>>num;

	cout<<"请依次输入"<<num<<"个元素:";
	while(num>0)
	{
		int data;
		cin>>data;
		InsertByTail(L,data);
		num--;
	}
	PrintStaticLink(L);

	InsertByTail(L,7);
	PrintStaticLink(L);

	//3.删除结点
	cout<<"请输入要删除的元素:";
	int data;
	cin>>data;
	deleteElement(L,data);
	PrintStaticLink(L);

	InsertByTail(L,8);
	PrintStaticLink(L);

	//4,按值插入
	insertElementByData(L,11,2);
	PrintStaticLink(L);

	//5.摧毁静态链表
	if(DestroyStaticlinkList(L))
		cout<<endl<<"摧毁成功!"<<endl;
}

int main()
{
	Test();
	system("pause");
	return 0;
}

9.运行结果展示

在这里插入图片描述
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

静态链表的基础操作(详解) 的相关文章

  • 在java程序中使用c++ Dll

    我正在尝试使用System LoadLibrary 使用我用 C 编写的一个简单的 dll UseDllInJava java import com sun jna Library import com sun jna Native imp
  • 通过增加索引之和来生成排序组合的有效方法

    对于启发式算法 我需要一个接一个地评估特定集合的组合 直到达到停止标准 由于它们很多 目前我正在使用以下内存高效迭代器块生成它们 受到 python 的启发 itertools combinations http docs python o
  • 如何使用 zlib 制作 .zip 文件

    我正在阅读zlib的文档 它相当详细 但我读到了这一行 输出数据将位于zlib格式 与 gzip 或zip formats http www zlib net zlib how html http www zlib net zlib how
  • 分段错误(核心转储)错误

    我的程序编译罚款 但在输入文件时出现 分段错误 核心转储 错误 我没有正确处理 ostream 吗 include
  • 将字节数组转换为托管结构

    更新 这个问题的答案帮助我编写了开源项目GitHub 上的 AlicanC 现代战争 2 工具 https github com AlicanC AlicanC s Modern Warfare 2 Tool 你可以看到我是如何阅读这些数据
  • 为什么Apache MPM prefork.c 使用互斥体来保护accept()?

    我坐下来读书Apache 的 MPM prefork c http code metager de source xref apache httpd server mpm prefork prefork c这段代码使用了一个名为accept
  • 在 C# 中生成 HMAC-SHA1

    我正在尝试使用 C 来使用 REST API API 创建者提供了以下用于 hmac 创建的伪代码 var key1 sha1 body var key2 key1 SECRET KEY var key3 sha1 key2 var sig
  • mprotect 之后 malloc 导致分段错误

    在使用 mprotect 保护内存区域后第一次调用 malloc 时 我遇到分段错误 这是执行内存分配和保护的代码片段 define PAGESIZE 4096 void paalloc int size Allocates and ali
  • TcpClient 在异步读取期间断开连接

    我有几个关于完成 tcp 连接的问题 客户端使用 Tcp 连接到我的服务器 在接受客户端后listener BeginAcceptTcpClient ConnectionEstabilishedCallback null 我开始阅读netw
  • 如何在 C++ 中将 CString 转换为 double?

    我如何转换CString to a double在 C 中 Unicode 支持也很好 Thanks A CString可以转换为LPCTSTR 这基本上是一个const char const wchar t 在 Unicode 版本中 知
  • 为什么具有相同名称但不同签名的多个继承函数不会被视为重载函数?

    以下代码片段在编译期间产生 对 foo 的调用不明确 错误 我想知道是否有任何方法可以解决此问题而不完全限定对 foo 的调用 include
  • C++11 动态线程池

    最近 我一直在尝试寻找一个用于线程并发任务的库 理想情况下 是一个在线程上调用函数的简单接口 任何时候都有 n 个线程 有些线程比其他线程完成得更快 并且到达的时间不同 首先我尝试了 Rx 它在 C 中非常棒 我还研究了 Blocks 和
  • 如何随着分辨率的变化自动调整大小和调整表单控件

    我注意到某些应用程序会更改控件的位置以尽可能适应当前的分辨率 例如 如果窗口最大化 则控件的设置方式应使整个 GUI 看起来平衡 是否可以使用 C 在 Visual studio 2010 中制作或实现此功能 Use Dock http m
  • 二叉树中的 BFS

    我正在尝试编写二叉树中广度优先搜索的代码 我已将所有数据存储在队列中 但我不知道如何访问所有节点并消耗它们的所有子节点 这是我的 C 代码 void breadthFirstSearch btree bt queue q if bt NUL
  • .NET 客户端中 Google 表格中的条件格式请求

    我知道如何在 Google Sheets API 中对值和其他格式进行批量电子表格更新请求 但条件格式似乎有所不同 我已正确设置请求 AddConditionalFormatRuleRequest formatRequest new Add
  • asp.net网格分页的SQL查询

    我在用iBatis and SQLServer 使用偏移量和限制进行分页查询的最佳方法是什么 也许我添加该列ROW NUMBER OVER ORDER BY Id AS RowNum 但这只会阻止简单查询的数据访问 在某些情况下 我使用选择
  • DataTable:通过 LINQ 或 LAMBDA 进行动态 Group By 表达式

    我有一个数据表 我想在其中对未指定数量的字段进行分组 发生这种情况的原因是用户可以选择他想要分组的字段 所以 实际上 我将选择推入列表中 在这个选择上 我必须对我的数据表进行分组 想象一下这段代码 VB 或 C 都一样 public voi
  • C语言声明数组没有初始大小

    编写一个程序来操纵温度详细信息 如下所示 输入要计算的天数 主功能 输入摄氏度温度 输入功能 将温度从摄氏度转换为华氏度 独立功能 查找华氏度的平均温度 我怎样才能在没有数组初始大小的情况下制作这个程序 include
  • 带有私有设置器的 EFCore Base 实体模型属性 - 迁移奇怪的行为

    实体模型继承的类内的私有设置器似乎会导致 EFCore 迁移出现奇怪的问题 考虑以下示例 其中有多个类 Bar and Baz 继承自Foo 跑步时Add Migration多次命令 添加 删除private修饰符 生成的模式在多个方面都是
  • C#中为线程指定特殊的cpu

    我有 2 个线程 我想告诉其中一个在第一个 cpu 上运行 第二个在第二个 cpu 上运行 例如在具有两个 cpu 的机器中 我怎样才能做到这一点 这是我的代码 UCI UCIMain new UCI Thread UCIThread ne

随机推荐

  • [架构之路-181]-《软考-系统分析师》-19- 系统可靠性分析与设计 - 2-容错性: 软件容错技术

    目录 前言 1 9 4 软件容错技术 19 4 1 N 版本程序设计 1 与 通 常 软 件 开 发 过 程 的 区 别 2 其 他 需 要 注 意 的 问 题 19 4 2 恢复块方法 19 4 3 防卫式程序设计 预防性设计 广泛使用
  • HTML5移动开发常用meta标签

    html
  • 在IBM p6 570 LPAR之间动态切换磁盘机/光驱

    小机上的一些外设比如磁盘机和光驱平时用的不多 所以大多都是在一台小机的各LPAR之间共享使用的 这些IO设备在不同的LPAR之间使用时 只能被一个LPAR独占 所以必要的时候就必须要做切换 客户的一台p6 570 里面做了4个LPAR 需要
  • 回顾篇-mysql索引-读书笔记

    事务日志 事务日志可以帮助提高事务的效率 使用事务日志 存储引擎在修改表的数据时只需要修改其内存拷贝 再把该修改行为记录到持久在硬盘上的事务日志中 而不用每次都将修改的数据本身持久到磁盘 事务日志采用的是追加的方式 因此写日志的操作是磁盘上
  • STM32学习---时钟系统

    1 时钟树 STM32的时钟系统比较复杂 我们主要通过时钟树来了解单片机内部的时钟配置情况 时钟树可以从开发指南中找到 以f1为例 学习一下他的树 明确几个缩写定义 AHB 先进高速总线 APB1 先进设备总线1 APB2 先进设备总线2
  • ORM总结(单表,一对多,多对多)

    一 表记录的增删改查 单表操作 1 添加 时间的格式必须写成YYYY MM DD 2 删除 filter筛选多条记录 返回的是QuerySet集合对象 3 修改 这三种都是类 objects 4 查询 values是具体拿一个字段 不再拿整
  • Linux内核memcpy的不同实现

    目录 1 概述 2 高级SIMD和浮点寄存器介绍 2 NEON指令 2 1 VLDR 2 2 VLDM 2 3 VSTR 2 4 VSTM 3 ARM架构程序调用寄存器使用规则 3 1 ARM寄存器使用规则 3 2 NEON寄存器使用规则
  • 【Python】range函数

    range函数 Python3 range 函数返回的是一个可迭代对象 类型是对象 而不是列表类型 所以打印的时候不会打印列表 res range 6 print res gt gt gt range 0 6 打印出来的不是列表 Pytho
  • 2.1 主窗口

    Qt用QMainWindow和相关的类来管理主窗口 QMainWindow继承自QWidget类 以下介绍几种常用操作 1 close 关闭当前窗口 2 hide 隐藏当前窗口 相当于 setVisible false 设置窗口可见或是不可
  • CocosCreator3.0加载远程图片资源

    在微信小游戏平台 需要获取了微信头像 对于这个需求 需要这样来做 获取微信用户信息 得到微信小游戏头像的http地址 在Cocos引擎使用loadRemote来加载 这其中的问题在于 使用loadRemote加载时获得的对象和2 x的版本不
  • redis服务停止(NOAUTH Authentication required)问题处理

    redis服务停止报NOAUTH Authentication required错误 处理方法 命令处理 redis cli a 密码 p 6379 shutdown 脚本处理 进入脚本文件 stop命令增加密码 完整配置文件 bin ba
  • 【统计模型】生存分析基本知识介绍

    目录 一 生存分析介绍 1 生存分析用途 2 传统方法在分析随访资料时的困难 1 生存时间和生存结局都是我们关心的因素 2 存在大量失访 3 显然 将失访数据无论是算作死亡还是存活都不合理 3 生存分析的优劣势 1 优势 2 劣势 4 生存
  • 机器学习经典算法,原理及代码实现

    机器学习知识体系 岭回归和LASSO回归 朴素贝叶斯 支持向量机 Logistic回归 K 近邻算法 线性回归 决策树 EM最大期望算法 Apriori算法 自适应增强 Adaboost 算法 PageRank算法
  • java.lang.ClassCastException: com.sun.proxy.$Proxy0 cannot be cast to java.sql.Connection异常问题解决

    Connection proxy Connection Proxy newProxyInstance Connection class getClassLoader Connection class getInterfaces new In
  • 数据结构——线性结构(7)——链队列的实现

    链队列的实现 头文件 这部分文件实现我们之前所使用的queue类 它主要的原理为 后进后出 LILO ifndef Queue h define Queue h 类型 Queue
  • 使用vue-video-player,播放rtmp直播流

    可直接在新的页面复制使用 测试可用
  • 对cpu与load的理解及线上问题处理思路解读

    前言 2019双11还有不到2个月就要到来了 大家也都知道服务器在大促期间由于流量的增加势必导致机器的cpu与load变高 因此趁着这个时机正好再好好学习 巩固一下cpu和load的概念 为双11做准备的同时也是增加自己的技能储备 不过cp
  • 华为OD机试真题- 宜居星球改造计划-2023年OD统一考试(B卷)

    题目描述 2XXX年 人类通过对火星的大气进行宜居改造分析 使得火星已在理论上具备人类宜居的条件 由于技术原因 无法一次性将火星大气全部改造 只能通过局部处理形式 假设将火星待改造的区域为row column的网格 每个网格有3个值 宜居区
  • Unity Shader入门精要第七章 基础纹理渐变纹理

    Unity系列文章目录 文章目录 Unity系列文章目录 前言 一 渐变纹理是什么 参考 前言 尽管在一开始 我们在渲染中使用纹理是为了定义一个物体的颜色 但后来人们发现 纹理 其实可以用于存储任何表面属性 一种常见的用法就是使用渐变纹理来
  • 静态链表的基础操作(详解)

    目录 一 闵版 1 完整代码 2 运行结果 二 钦版 1 结构体的创建 2 静态链表的初始化 3 尾插法 4 按值插入 5 删除元素 6 打印静态链表 7 摧毁链表 8 完整代码 9 运行结果展示 一 闵版 1 完整代码 include