线性表和单链表的相关操作

本文介绍了数据结构中的线性表,包括顺序表的初始化、取值、查找、插入和删除操作。同时,详细阐述了单链表的特性,提供了链表的初始化、取值、查找、插入和删除的实现方法,以及链表的创建和逆转操作。代码示例展示了如何在C++中进行这些基本操作。
摘要由CSDN通过智能技术生成

代码参考了严版数据结构,仅用于个人的知识整理。

线性表:
    顺序储存(随机存取)的线性表一般称为顺序表
    定义顺序表:

typedef struct
	{
		int em1;
		int em2;
	}ElemType;

	typedef struct
	{
		ElemType* elem; //储存顺序表的储存空间的第一个元素的地址 类似数组a[10] 中的a
	    int length;   //储存顺序表的长度
	}Sqlist;

​


    初始化:需要注意,当空间分配失败时,返回0,成功返回1.
    1.定义一个顺序表
    2.给顺序表的分配一个空间,并用elem指针指向空间
    3.将表长设为0

int InitList(Sqlist& L)
	{
		L.elem = new ElemType[MaxSize];
		if (!L.elem) return 0 ;
		L.length = 0;
        return 1;
	}

取值:获取指定位置i的值
    1.判断位置是否合理,不合理返回0
    2.若合理则将下标为i-1的值给e(e用于接收数据)

int GetElem(Sqlist L, int i, ElemType& e)
	{
		if(i<1||i>L.length) return 0
		else {
			e = L.elem[i - 1];
			return 1;
		     }
	}

    查找:已知数据e,要在顺序表中找到其所在位置
    1.找不到返回0,找到返回i+1

int LocationElem(Sqlist L, ElemType e)
	{
		for (int i = 0; i < L.length; i++)
		{
			if (e == L.elem[i]) return i + 1;
		}
		return 0;
	}

    插入:在顺序表的i位置插入一个新的数据
    1.首先将i和其之后的数据全部向后移动一个单位,然后给i位置赋值
    2.注意插入的范围,只能在1到L.length+1之间 i==L.length+1 时,不需要移动,而i==L.length 需要将最后一个移动
    3.表满了,就不能插入

int ListInsert(Sqlist L, int i, ElemType e)
	{
		if(i<1 || i>L.length+1) return 0;
		if (L.length == MaxSize) return 0;
		for (int j = L.length-1; j>=i-1; j--)
		{
			L.elem[j + 1] = L.elem[j];
	}
		L.elem[i - 1] = e;
		L.length++;
		return 1;
	}


    删除:
    1.如果表长为0,返回0
    2.删除的范围只能在1到L.length之间<超过该区间返回0

int ListDelete(Sqlist L, int i)
	{
		if (L.length == 0) return 0;
		if (i<1 || i>L.length) return 0;
		for (int j = i; j < L.length; j++)
		{
			L.elem[j-1] = L.elem[j ];//相当于覆盖掉i-1位置的数
	    }
		L.length--;
        return 1;
	}

单链表:
    元素之间的逻辑关系由结点的指针指示:这种储存结构为非顺序映像或链式映像

   为了方便讨论链表,引出几个概念:
    首元结点:链表真正意义上的第一个元素
    头结点:在首元结点之前设置的结点,指针域指向首元结点,其数据域一般不储存数据,也可用于储存该表的相关信息
    头指针:有头结点就指向头结点
    增加头节点可以方便首元节点的操作,无需对其特殊处理

    判断链表是否为空:

        1.无头结点,L==NULL为空

        2.有头结点,L->next==NULL

    初始化:
    1.生成结点作为头结点,头指针指向头结点
    2.头结点的指针域置空


	struct ElemType
{
	int a;
};
typedef struct LNode
{
    ElemTye  data; //数据
	struct LNode* next;//指向下一级的指针
}LNode, * LinkList;
int InitList(LinkList& L)
{
	L = new LNode; //生成一个头结点
	L->next = NULL;
	return 1;
}

    取值:从首元结点出发,遍历
    1.i的取值只能是1到n,超过这个范围出错

int GetElem(LinkList L, int i, ElemType & e)
{
	LinkList p = L->next;
	int j = 1;
	while (p && j < i)
	{
		p = p->next;
		j++;
	}
	if (!p || j > i) return 0; //i值不合法i>n    这时候p=NULL   或i<=0 j>i
	e = p->data;
	return 1;
}

    查找:从首元结点出发,遍历
    1.找到相等就返回

LNode* LocateElem(LinkList L, ElemType e)
{
	LNode* p = L->next;
	while (p && e != p->data)
	{
		p = p->next;
	}
return p;
}

    插入:将值为e的新结点插入表中第i个位置
    1.生成一个结点s,设置数据域为e,设置它的指针域指向ai,ai-1的指针域指向s

int ListInsert(LinkList& L, int i, ElemType  e)
{
	LNode* p = L->next;
	int j = 1;
	while (p && j < i - 1)
	{
		p = p->next;
		j++;
	}
	if (!p || j > i - 1) return 0;
	LinkList s = new LNode;
	s->data = e;
	s->next = p->next;
	p->next = s;
	return 1;
}


    删除:将第i个位置的结点删除
    1.找到i结点的上方,i-1

void DestoryList(LinkList& L, int i)
{
    LinkList p = L->next;
	int j = 1;
	while (p && j < i-1)
	{
		p = p->next;
		j++;
	}
	if (!p || j > i-1) return ; //i-1值不合法i-1>n    这时候p=NULL   或i-1<=0 j>i-1
	//找到需要删除的结点的上一个
    LinkList m=p->next;
    p->next=p->next->next;
    free(m);//将其释放
}


    单链表的创建:
    1.前插法
    2.尾插法

void CreateList_H(LinkList& L, int n)
{
	//头插
	L = new LNode;
	L->next = NULL;//建立头结点
	while (n > 0)
	{
		LinkList p = new LNode;
		cin >> p->data;
		p->next = L->next;
		L->next = p;
		n--;
	}
	//尾插
	LinkList r = L;
	while (n > 0)
	{
		LinkList p = new LNode;
		cin >> p->data;
		r->next = p;
		r = p;
		n--;
	}
}
// 头结点  1 2 3 4 5

    单链表的逆转:

void Listreserve(LinkList& L,int n)
{
	LinkList now, old, tem;
	now = L->next;
	old = L->next;
	tem = L->next->next;
	while (n - 1 > 0)
	{
		now = tem;
		tem = now->next;
		now->next = old;
		old = now;
		n--;
	}
	L->next->next = tem;
	L->next = now;
}

链表的数据域涉及比较的时候不能像上述代码那么简单,这样是会报错的,要将数据域的结构体中的成员一个一个比较。

代码如果有遗漏的地方,欢迎各位大佬指出!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值