C、C++线性表基本操作的详细介绍

前言

线性表包括两部分顺序表和链表,是数据结构的基础,在此主要就算法进行分析和总结,作为记忆了解,未做具体实现。

提示:以下是本篇文章正文内容,下面案例可供参考

一、顺序表

#define LISST_INIT_SIZE 100
#define LISTINCREMENT 10
#define OK 0
#define OVERFLOW 1
typedef int ElemType;
typedef int Status;

1、定义

typedef struct{
			int* elem; //定义存储基地址
			int length; //当前顺序表长度
			int listsize; //当前分配的大小
			}SqList;

2、初始化构建

Status InitList_Sq(SqList &l){
	L.elem =(ElemType *)malloc(LISST_INIT_SIZE*sizeof(ElemType));
	if(!L.elem)
	exit(OVERFLOW);
	L.length=0;
	L.listsize=LISST_INIT_SIZE;
	return OK;

3、插入操作

在第i的位置插入元素e

1、算法解释

  1. 检查i的合法性
  2. 检查储存空间
  3. 标记插入位置
  4. 将插入位置后面的元素依次向下移动一位(注意从后往前依次移动,以移动位置小于插入位置结束循环)

2、算法实现

Status LIstInsert_Sq(Sqlist &L,int i, ElemType e){
SqList *newbase,*p,*q;
	//在第i个位子插入元素e
	if(i<1||i>L.length+1)
	return ERROR;
	//分配存储空间
	if(L.length>L.listsize){
		newbase=(ElemType *)realloc(l.elem,		(Listsize+LISTINCREMENT)*sizeof(ELemType);
	if(!newbase)
	exit(OVERFLOW);
	L.elem=newbase;
	L.listsize+=LISTINCREMENT;
	}
//记录插入位置
	q=&L.elem[i-1];
	for(p=L.elem[length-1];q<=p;p--)
	{
		*(p+1)=*p
	}
	*p=e;
	L.length++;//更新表长
	return OK;
}

4、删除操作

在第i的位置插入元素e

1、算法解释

  1. 检查i的合法性
  2. 记录删除的位子
  3. 找到删除元素并赋值给e
  4. 被删除元素后面的元素都想上移动一位(找到表尾元素,以移动位子地址大于表尾地址结束循环)

2、算法实现

Status LIstDelete_Sq(Sqlist &L,int i, ElemType &e){
SqList *p,*q;
	//在第i个位子删除元素
	if(i<1||i>L.length+1)
	return ERROR;
//记录删除位置
	p=&L.elem[i-1];
	e=*p;
	//表尾元素
	q=&L.elem[L.length-1];
	for(++p;p<=q;p++)
	{
		*(p-1)=*p;
	}
	L.length--;//更新表长
	return OK;
}

5、合并操作

已知La和Lb的元素按照非递减的顺序排列归并为Lc也为按值非递减排列

1、算法解释

  1. 记录La、Lb的操作地址
  2. 计算Lc的长度并为其分配空间
  3. 记录La、Lb的表尾位置
  4. 合并-比较两个表的元素,值较小的存入Lc(注意:以任意一表完全存入Lc结束循环)
  5. 检查La、Lb是否还有剩余元素,如果有剩余依次存入Lc

2、算法实现

void MergeList_Sq(SqList La,SqList Lb,SqList &Lc){
//分别记录La、Lb的当前操作地址
SqList *pa,*pb,*pc,*pa_last,*pb_last;
pa=La.elem;
pb=Lb.elem;
Lc.listsize=La.length+Lb.length;
pc=Lc.elem=(ElemType *)mallod(Lc.listsize*sizeof(ElemType);
if(!pc){
		exit(OVERFLOW);//分配失败
		}
		//记录顺序表尾的地址
pa_last=La.elem+La.length-1;
pb_last=Lb.elem+Lb.length-1;
while(pa<pa_last&&pb<pb_last){
	if(*pa<*pb)
	{
	 //*pc++=*pa++;
		*pc=*pa
		pc++;
		pa++;
	}
	else
	{
	//*pc++=*pb++;
		*pc=*pb;
		pc++;
		pb++;
	}
	while(pa<pa_last)
	{
		*pc++=*pa++;
	}
	while(pb<pb_last)
	{
		*pc++=*pb++;
	}
}

二、链表

#define OK 0
#define OVERFLOW 1
typedef int ElemType;
typedef int Status;

1.单链表

1、定义

typedef int ElemType;
typedef struct LNode{
	ElemType date;
	struct LNode *next;
	}LNode,*LinkList;

2、插入

在带头结点L中的第i个位置之前插入e

1、算法解释

  1. 找到第i-1个结点记录为P
  2. 判断是否找到该结点
  3. 生成新结点S赋值进行插入L中

2、算法实现

status ListInsert(LinkList &l,int i;ElemType e){
	LinkList p=L,S;
	int j=0;
	while(p&&j<i-1){
	p=p->next;
	j++;
	}
	if(!p||j>i-1)
	return ERROR;
	//生成新节点
	S=(LinkList)malloc(sizeof(LNode));
	S->date=e;
	S->next=p->next;
	p->next=S;
	return OK;
	}

3、删除

在带头结点的单链表L中删除第i个元素,并返回e

1、算法解释

  1. 记录头结点的位置
  2. 寻找第i个结点,并用p记录其前驱
  3. 检查删除位置的合理性
  4. 记录第i个结点,取其值赋值给e
  5. 将第i-1个结点指向i+1
  6. 释放第i个结点

2、算法实现

status ListDelete_L(LinkList &L,int i,ElemType &e){
LinkList p=L,q;
int j=0;
while(p->next&&j<i-1){
	p=p->next;
	j++;
}
if(!(p-next)||j>i-1)
return ERROR;
	q=p->next;
	p->next=q->next;
	e=q->date;
	free(q);
return OK;

4、查找

代码如下(示例):找到第i个位置的元素,并赋值给e

1、算法解释

  • 将p指向第一个结点
  • 寻找第i个结点(以p为空或者j>i结束循环)
  • 判断是否找到结点i
  • 取结点i的元素值

2、算法实现

status GetElem_L(LinkList L,int i,ElemType &e){
	LinkList p;
	int j=1;
	p=L->next;

	while(p&&j<i){
		p=p->next;
		j++;
		}
	if(!p||j>i)
		return ERROR;
	e=p->data;
	return OK;
	}

5、合并有序链表

已知La、Lb按值非递减 Lc也是按值非递减(带头结点)

1、算法解释

  1. 更新Pa、Pb、Pc的初始化位置都指向第一个结点
  2. 以Pa、Pb都非空为条件,比较其存储数据,较小的连接在Lc上,更新Pc和Pa(Pb)
  3. 插入剩余结点
  4. 释放未使用的空头结点

2、算法实现

void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc){
//记录结点
LinkList Pa,Pb,Pc;
Pa=La->next;
Pb=Lb->next;
Pc=Lc=La;
while(Pa&&Pb){

if(Pa->data<=Pb->data){
	Pc->next=Pa;
	Pc++;
	Pa++;
	}
else{
	Pc->next=Pb;
	Pc++;
	Pb++;
	}
}
Pc->next=pa? Pa:Pb;
free(Lb);
}

6、创建链表

输入n个元素的值,建立带头结点的单链表L

1、逆位序(头插法)

算法思路

  1. 创建头结点
  2. 循环插入结点
  3. 将新结点插入表头的后面
  4. 更新表头的next ##### 算法实现

算法实现

void GreateList_L(LinkList &L,int n){
//建立头结点
LinkList L,P;
L=(LinkList)malloc(sizeof(LNode);
L->next=NULL;
for(i=0;i<n;i++){
	P=(LinkList)malloc(sizeof(LNode);
	scanf("%d",&P->data);//以整型为例
	P->next=L->next;
	L->next=P;
	}
}

2、顺位序(尾插法)

算法思路

  1. 创建头结点
  2. 循环插入结点
  3. 将新结点插入表尾
  4. 记录表尾位置并更新

算法实现

void GreateList_L(LinkList &L,int n){
//建立头结点
LinkList L,P;
L=(LinkList)malloc(sizeof(LNode);
L->next=NULL;
Q=L;
for(i=0;i<n;i++){
	P=(LinkList)malloc(sizeof(LNode);
	scanf("%d",&P->data);//以整型为例
	Q->next=P
	Q=P;
	}
	q->next=NULL;
}

2.循环链表

与单链表类似,只是表尾结点的next指向了头结点,循环条件为是否等于表头元素,不再具体叙述!

3.双向链表

1、定义

//定义一个双向链表
typedef struct DuLNode{
	ELemType data;//数据元素
	struct DuLNode *prior;//前驱指针
	struct DuLNode *next;//后继指针
}DuLNode,*DuLinkList;

2、插入

在带头结点的双向循环链表L中的第i个结点(P)之前插入结点S的元素e

算法思路

  1. 检查i的合法性(1<=i<=表长+1)
  2. 插入

算法实现

S->data=e;//赋值
S-prior=p->prior;
P->prior->next=S;
S->next=P;
P->prior=S;

3、删除

在带头结点的双向循环链表L中删除第i个结点(P)并将其数据复制给元素e

算法思路

  1. 检查i的合法性(1<=i<=表长)
  2. 删除

算法实现

e=P->data;
q=P;
P->prior->next=P->next;
P->next->prior=P->prior;
free(q);//释放结点P

总结

到此顺序表和链表的基本操作算法基本介绍完成,希望能对初学者有所帮助,后续会对数据结构后面的内容进行更新。更多相关C、C++线性表基本操作内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++语言实现线性表之数组实例

    本文实例讲述了C++语言实现线性表之数组.分享给大家供大家参考.具体分析如下: 感觉用C++中的构造函数.析构函数等类的特点来描述一些数据结构更加易读,更加合理,便捷.但有一个问题,编译器不支持模板的分离编译,很不舒服 #include <iostream> using namespace std; template<class T> class CArray { public: CArray(const int &iMax); CArray(); ~CArray(); v

  • C++通过类实现线性表

    本文实例为大家分享了C++类实现线性表的具体代码,供大家参考,具体内容如下 下图是标准C语言实现的函数定义 下面可以用C++实现,第一个参数就是this的指针 list.h函数 #pragma once typedef int Elem; class List { public: List(int size); ~List(); void ClearList(); // 将数组长度设为0 bool ListEmpty(); // 判断数组是否为空 int ListLength(); // 获取数

  • C++实现线性表链式存储(单链)

    本文实例为大家分享了C++实现线性表链式存储的具体代码,供大家参考,具体内容如下 实现的功能: 1.定义了三中传入不同参数的构造函数,用于初始化创建不同的链表: 2.能实现增.删.查等基本功能: 存在的问题: 当创建一个已知大小的空链表后,链表中的数据并不为空,见下图: 下面是代码及测试结果: singlelinklist.h #pragma once #include "iostream" #include "exception" #include "s

  • 解析C++的线性表链式存储设计与相关的API实现

    基本概念 链式存储定义: 为了表示每个数据元素与其直接后继元素之间的逻辑关系,每个元素除了存储本身的信息外,还需要存储指示其直接后继的信息. 表头结点: 链表中的第一个结点,包含指向第一个数据元素的指针以及链表自身的一些信息. 数据结点: 链表中代表数据元素的结点,包含指向下一个数据元素的指针和数据元素的信息. 尾结点: 链表中的最后一个数据结点,其下一元素指针为空,表示无后继. 链表技术领域推演 链表链式存储_api实现分析: 在C语言中可以用结构体来定义链表中的指针域,链表中的表头结点也可以

  • C++语言实现线性表之链表实例

    本文实例讲述了C++语言实现线性表之链表实现方法.分享给大家供大家参考.具体分析如下: 插入.删除结点的代码有点多,但这样提高了代码的可读性,且不增加时间复杂度,不会影响程序性能 #include <iostream> using namespace std; template<typename T> class CList; template<class T> class Node { friend CList<T>; private: T m_data;

  • C++实现动态线性表

    之前在学习c语言的时候用c语言实现了动态线性表.现在再使用c++实现一下动态线性表. 相关数据结构方面就不多说了.在之前的博客里也有.下面就直接来实现吧. 这里使用指针来遍历数组,这样在算size,capacity的时候,直接用指针相减的方式就可以得到元素个数,以及容量. Vector.h #include <iostream> #include<assert.h> #include<stdio.h> #include<string.h> //用typede

  • C++ 数据结构线性表-数组实现

    C++ 数据结构线性表-数组实现 线性表的数组实现,实现几个核心的功能,语言是C++,如果有更好的想法和意见,欢迎留言~~~ /* Author : Moyiii * 线性表的数组实现,仅作学习之用,当然如果 * 你想拿去用,随你好啦. */ #include<iostream> using namespace std; //顺序表 class SeqList { public: //构造函数,接受一个默认的列表大小 SeqList(int size = MAX_LIST_SIZE); //析

  • C、C++线性表基本操作的详细介绍

    前言 线性表包括两部分顺序表和链表,是数据结构的基础,在此主要就算法进行分析和总结,作为记忆了解,未做具体实现. 提示:以下是本篇文章正文内容,下面案例可供参考 一.顺序表 #define LISST_INIT_SIZE 100 #define LISTINCREMENT 10 #define OK 0 #define OVERFLOW 1 typedef int ElemType; typedef int Status; 1.定义 typedef struct{ int* elem; //定义

  • Mysql表的操作方法详细介绍

    目录 创建表 查看表结构 修改表 删除表 创建表 语法: CREATE TABLE table_name ( field1 datatype, field2 datatype, field3 datatype ) character set 字符集 collate 校验规则 engine 存储引擎; 说明: field 表示列名 datatype 表示列的类型 character set 字符集,如果没有指定字符集,则以所在数据库的字符集为准 collate 校验规则,如果没有指定校验规则,则以

  • SQL Server 2008中的数据表压缩功能详细介绍

    SQL Server 2005 SP2为我们带来了vardecimal功能,当时针对decimail和numeric数据类型推出了新的存储格式--vardecimal.vardecimal存储格式允许 decimal和numeric数据类型的存储作为一个可变长度列. 这项功能使得原来定长的decimal数据在数据文件中以可变长的格式存储,据称这项功能可以为典型的数据仓库节省30%的空间,而SQL Server 2008在这一基础上又进一步增强了数据压缩功能.SQL Server 2008现在支持

  • C语言超详细讲解数据结构中的线性表

    目录 前言 一.分文件编写 1.分文件编写概念 2.代码展示 二.动态分布内存malloc 1.初识malloc 2.使用方法 三.创建链表并进行增删操作 1.初始化链表 2.在链表中增加数据 3.删除链表中指定位置数据 四.代码展示与运行效果 1.代码展示 2.运行效果 总结 前言 计算机专业都逃不了数据结构这门课,而这门课无疑比较难理解,所以结合我所学知识,我准备对顺序表做一个详细的解答,为了避免代码过长,采用分文件编写的形式,不仅可以让代码干净利落还能提高代码可读性,先解释部分代码的含义,

  • C语言超详细讲解线性表

    目录 1. 顺序表 1.1 管理结点 1.2 顺序表的插入 1.3 顺序表的删除 1.4 顺序表的扩容 2. 链表 2.1 定义 2.2 头部插入 2.3 尾部插入 2.4 任意位置插入 2.5 任意位置删除 2.6 虚头结点 1. 顺序表 顺序表是指用一段连续的地址,依次存放数据元素的线性数据结构.此种存储方式使得顺序表的物理结构与逻辑结构都是连续的. 与数组的区别:函数中的数组被存放在栈段中,而栈段有系统限制的大小(可使用ulimit -s查看系统限制的大小,单位为KB),因此顺序表往往使用

  • C语言 超详细介绍与实现线性表中的带头双向循环链表

    目录 一.本章重点 二.带头双向循环链表介绍 2.1什么是带头双向循环链表? 2.2最常用的两种链表结构 三.带头双向循环链表常用接口实现  3.1结构体创建 3.2带头双向循环链表的初始化  3.3创建新节点 3.4尾插 3.5打印链表 3.6头插 3.7尾删 3.8头删 3.9查找data(返回data的节点地址) 3.10在pos位置之前插入节点 3.11删除pos位置的节点 四.实现接口总结 五.在线oj训练与详解 一.本章重点 带头双向循环链表介绍 带头双向循环链表常用接口实现 实现接

  • C语言 超详细介绍与实现线性表中的无头单向非循环链表

    目录 一.本章重点 二.链表介绍 三.无头单向非循环链表常用接口实现 3.1动态申请一个节点 3.2单链表打印 3.3单链表尾插 3.4单链表的头插 3.5单链表的尾删 3.6单链表头删 3.7单链表查找 3.8单链表在pos位置之前插入x 3.9单链表删除pos位置的节点 四.在线oj训练 4.1移除链表元素(力扣) 4.2反转单链表(力扣) 一.本章重点 无头单向非循环链表介绍 无头单向非循环链表常用接口实现 在线oj训练 二.链表介绍 概念:链表是一种物理存储结构上非连续.非顺序的存储结构

  • C语言实现线性表的基本操作详解

    目录 前言 一.实训名称 二.实训目的 三.实训要求 四.实现效果 五.顺序存储代码实现 六.链式存储代码实现 前言 这里使用的工具是DEV C++ 可以借鉴一下 一.实训名称 线性表的基本操作 二.实训目的 1.掌握线性表的基本概念 2.掌握线性表的存储结构(顺序存储与链式存储) 3.掌握线性表的基本操作 三.实训要求 1.线性表可以顺序表也可以用单链表实现,鼓励大家用两种方式实现. 2.创建线性表时,数据从键盘输入整形数据 3.线性表类型定义和或各种操作的实现,可以用教材给出的方法,也可以自

  • C语言线性表中顺序表超详细理解

    目录 一.本章重点 二.线性表 三.顺序表 四.静态顺序表接口实现 4.1顺序表初始化 4.2顺序表打印 4.3顺序表尾插 4.4顺序表尾删 4.5顺序表头插 4.6顺序表头删 4.7顺序表任意位置插入 4.8顺序表任意位置删除 五.动态顺序表接口实现 5.1顺序表的初始化 5.2顺序表打印 5.3顺序表尾插 5.4顺序表尾删 5.5顺序表头插 5.6顺序表头删 5.7顺序表任意位置插入 5.8顺序表任意位置删除 六.在线0j练习 一.移除元素(力扣) 二.合并两个有序数组(力扣) 一.本章重点

  • 简单介绍线性表以及如何实现双链表

    线性表是一种线性结构,它是具有相同类型的n(n≥0)个数据元素组成的有限序列. 一.数组 数组有上界和下界,数组的元素在上下界内是连续的. 存储10,20,30,40,50的数组的示意图如下: 数组的特点:数据是连续的:随机访问速度快. 数组中稍微复杂一点的是多维数组和动态数组.对于C语言而言,多维数组本质上也是通过一维数组实现的.至于动态数组,是指数组的容量能动态增长的数组:对于C语言而言,若要提供动态数组,需要手动实现:而对于C++而言,STL提供了Vector:对于Java而言,Colle

随机推荐