数据结构之线性表

 顺序储存和链式储存


基础:结构体,数组,指针。

本文编译环境:Dev c++ 5.4.0

语言:c

序言:结构创建时候的typedef的作用!!!在c和c++不一样

在C中,必须用typedef,声明时就可以用 别名定义一个变量;

而在C++中,有两种方式,

方式一:不需要typedef即可定义,访问直接用别名访问数据,
方式二:用typedef定义,访问必须先用别名定义变量,再访问数据。

对 线性表的操作主要有,创建,求长,查找,插入,删除和显示。

先说顺序储存,其实就是利用数组来建立线性表,下面展示下顺序表的六个操作。

#define MAXLEN 100
#define datatype int 
//结构体的建立
typedef struct
{
	datatype data[MAXLEN];//数据存储 
	int last;//指向最后一个元素,-1为初始值 
}Seqlist;//名字

//顺序表创建 
Seqlist *Createlist()
{
	Seqlist *Lq;//定义头指针 
	Lq=(Seqlist *)malloc(sizeof(Seqlist));//给头指针分配空间 
	Lq->last=-1;//last的初始化 
	return Lq;//返回头指针 
} 
//求长直接last+1就可以了

//查找元素 
int Findlist(Seqlist *Lq,datatype i)//引入头指针和被查元素 
{
	int j;
	for(j=0;j<=Lq->last;j++)
	{
		if(Lq->data[j]==i) return j;//返回被查元素出现的第一次位置 
	}
	return -1;//没有相匹配返回查找失败 
} 

//插入元素 
int Insertlist(Seqlist *Lq,int i,datatype x)//引入头指针,被插元素的位置和被插元素 
{
	int j;
	if(Lq->last==MAXLEN||i<0||i>Lq->last+1) return -1;//插入元素位置有误或者已满,报错 
	for(j=Lq->last+1;j>i+1;j--)
	{
		Lq->data[j]=Lq->data[j-1];//被插入元素位置的往后所有元素往后移动 
	}
	Lq->data[i]=x;//插入元素 
	Lq->last++;//数据长度加1 
	return 1;//返回成功 
} 

//删除元素 
int Insertlist(Seqlist *Lq,int i)//引入头指针,被删元素的位置 
{
	int j;
	if(i<0||i>Lq->last) return -1;//删除元素位置有误报错 
	for(j=i;j<Lq->last;j++)
	{
		Lq->data[j]=Lq->data[j+1];//被删除元素位置,被后一位占据 
	}
	Lq->last--;//数据长度减1 
	return 1;//返回成功 
} 

//显示所有元素
void Looklist(Seqlist *Lq)//引入头指针,被删元素的位置 
{
	int j;
	for(j=0;j<=Lq->last;j++)
	{
		printf("%d",Lq->data[j]);//输出 
	}
} 

线性表就是个数组操作,删除和插入操作部分利用循环进行数据覆盖,优点是创建简单,缺点是局限性很大,必须先开垦一部分内存,不管用没用的到,而且很容易溢出。再比较下一个方法这些缺点就解决掉了。

相比线性表,线性链表就显得重要的多,这里强调一下线性链表的六个操作方法。

#include <stdio.h>
#include <stdlib.h>
#define MAXLEN 100
#define datatype int 

//结构体的建立
typedef struct link
{
	datatype data;//数据存储 
	struct link *next;//指向下一个节点
}Seqlist,*Seqlink;//名字

//线性链表创建,这个方法意义不大,但是重要的是个思想
Seqlist *Createlist()
{
	link *head;//定义头指针 
	head=(link *)malloc(sizeof(link));//分配存储空间 
	return head;//返回头指针 
}

//求长 
int Lenlist(link *head)//引入头指针 
{
	int i=0;//计数器 
	while(head!=NULL)
	{
		i++;//不为空计数器加1 
		head=head->next; //往下递增 
	}
	return i;//返回长度 
}

//查找
Seqlist *Searchlist(Seqlist *head,datatype x)//引入头指针和被查找元素 
{
	while(head!=NULL)
	{
		if(head->data==x) return head;//找到返回指针 
		head=head->next;//遍历下一个 
	}
	return NULL;//返回为空 
} 

//删除 
Seqlist *Deletelist(Seqlist *head,datatype x)//引入头指针和被删除元素 
{
	Seqlist *p,*s;
	s=head;//存放头指针 
	while(head!=NULL)
	{
		if(head->data==x)
		{
			p->next=head->next;//让当前的上一步指针指向当前的下一步指针 
			free(head);//释放被删除的指针资源 
			return s;//返回删除完成后的头指针 
		}
		p=head;//在遍历下一个之前,先存起来,等到下一步,这个就是上一步的指针 
		head=head->next;//遍历下一个 
	}
	return NULL;//返回为空 
} 

//显示 
void Looklist(Seqlist *head)//引入头指针
{
	while(head!=NULL)
	{
		printf("%d\n",head->data);//输出 
		head=head->next;//遍历下一个 
	}
} 

int main(int argc, char *argv[]) {
	int i;
	Seqlist *head=NULL,*b;
	for(i=0;i<5;i++)
	{
		Seqlist *a=(link *)malloc(sizeof(link));
		a->data=i;
		a->next=head;
		head=a;
	}
	Looklist(head);//查看当前指针所有内容
	//printf("%d\n",Lenlist(head));//输出当前长度
	//printf("%d",Searchlist(head,3)->data);//输出被查找元素的值
	Looklist(Deletelist(head,3));//删除后并可以查看
	return 0;
}

这里在线性链表的基础上再补充一下,循环链表和双向链表。

循环链表:将线性的单向链表最后一个节点的指针域指向头节点,整个链表头尾节点相连形成一个环,就构成了单循环链表。

双向链表:

//结构体的建立
typedef struct link
{
	datatype data;//数据存储 
	struct link *front;//指向前一个结点
        struct link *rear;//指向后一个结点 
}Seqlist,*Seqlink;//名字差别就在,访问某个结点时候,可以直接访问上一个或者下一个结点。

在学习这个线性链表时候,有个思想是不同于线性表的,就是线性链表是从头部进行操作的,其添加也是从头部添加,这里需要注意下(下划线部分的操作,需要深刻理解)。

这些代码都是跑过的,建议大家还是自己亲手敲一遍加深印象,作者这里也是一字一字敲出来的,要避免眼高手低。

本章的内容大家可以私信我,我也会第一时间回复大家的,差不多暑假两个月,复习下这些基本知识,其他的问题也可以问我,就算我不知道的,在能力范围之内的一定竭尽全力为你们解答。我的QQ:932824098.

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值