线性表的存储结构

线性表的概念

线性表是零个或多个数据元素的有限序列,并且线性表中的元素类型必须相同,线性表在物理存储上可以分为顺序存储结构和链式存储结构。
顺序存储结构:在内存空间中开辟一片连续的空间,然后把数据有序进行存储的一种方式。线性表的顺序存储结构类似于c语言中的数组,但两者的差别在于数组的长度是基本不变的,数组在申请内存空间的时候就已经确定其大小,而线性表的长度代表当前的元素个数,线性表的长度随元素的增删而动态变化。线性表的长度<=线性表的最大容量,即:线性表的当前长度<=数组的长度
链式存储结构:单链表不需要用地址连续的存储单元来实现,因为它不要求逻辑上相邻的两个数据元素物理上也相邻。单链表的每个结点包括指针域 (存放下一个结点的位置信息)和数据域(存放数据),它是通过建立起数据元素之间的逻辑关系,因此对线性表的插入和删除不需要移动数据元素,只需要修改

线性表的顺序存储结构思路与代码

  • 顺序存储结构的三大属性
    1.数据类型Data
    2.线性表的最大容量MaxSize
    3.线性表的当前长度length

    const int MaxSize=1e8;
    typedef int Elemtype;//Elemtype代表元素类型,这里用的int
    struct sqlist
    {
    	Elemtype data[MaxSize];
    	int length;
    }sqlist;
    
  • 顺序结构的删除和插入
    1.插入元素:判断异常,将元素插入到线性表中,插入元素位置后的所有元素后移,链表长度加一。
    2.删除元素:判断异常情况,将元素从线性表中删除后,删除元素位置后面的所有元素往前移,线性表长度减一。

#include<stdio.h>
#include<malloc.h>
const int MaxSize=1e8;
typedef int Elemtype;//Elemtype代表元素类型,这里用的int
typedef struct 
{
	Elemtype data[MaxSize];
	int length;
}sqlist;
bool listinsert(sqlist *L,int x,Elemtype e)//x代表插入元素位置 
{
	int j;
	if(L->length==MaxSize)	return false;//判断是否在最大容量内 
	if(x<1||x>L->length+1)	return false;//判断插入位置是否正常
	if(x<L->length)//判断位置是否在尾部 
		for(j=L->length-1;j>=x-1;j--)
			L->data[j+1]=L->data[j];
	L->data[x-1]=e;
	L->length++;
	return true;
}
bool listdelete(sqlist *L,int x,Elemtype *e)
{
	int j;
	if(L->length==0)	return false;//判断是否为空
	if(x<1||x>L->length)	return false;//判断删除位置是否正常
	*e=L->data[x-1];
	if(x<L->length)//判断位置是否在尾部 
		for(j=x;j<L->length;j++)
			L->data[j-1]=L->data[j];
	L->length--;
	return true;
}
int main()
{
	int n,i,k;
	Elemtype e;
	sqlist *L=(sqlist*)malloc(sizeof(sqlist));
	printf("输入起始线性表有n个元素\n");
	scanf("%d",&n);
	printf("接着输入n个元素\n");
	for(i=1;i<=n;i++)
	{
		scanf("%d",&e);
		if(!listinsert(L,i,e))	printf("插入异常\n");
	}
	printf("输入你想要删除元素的位置\n");
	scanf("%d",&k);
	if(listdelete(L,k,&e))	printf("你删除的元素是%d\n",e);
	else	printf("删除异常\n"); 
	printf("表中元素有\n");
	for(int i=0;i<L->length;i++)		printf("%d ",L->data[i]);
	return 0;
} 

在这里插入图片描述

线性表的链式存储结构思路与代码

  • 链式存储结构的两大属性
  1. 数据域data
  2. 指针域next
  • 链式结构的插入和删除
  1. 插入元素:在单链表LL的某个结点q之后插入一个新节点的基本过程是:首先找到正确位置q,然后申请新结点p的结点信息赋值,最后将p插在q之后。
    在这里插入图片描述
    核心代码:

    p->next=q->next;
    q->next=p;

  2. 删除元素: 声明两人指针变量p,q一个用于工作指针,一个用于临时存储信息。把第一个结点赋值给q,然后循环进行,直到cnt等于传入值,将下一个结点赋值给p,p->Next=q->Next;然后释放q。
    在这里插入图片描述
    核心代码:

    q=p->next;
    p->next=q->next;
    free(q);

    #include<stdio.h>
    #include<stdlib.h>
    typedef struct LNode *linklist;//给结构题起别名 
    struct LNode{//同样的这里也空用elemtype来控制元素类型,这里就用的int 
    	int data;
        linklist next;
    };
    linklist listcreate()
    {
    	linklist ll=(linklist)malloc(sizeof(linklist));
    	ll->next=NULL;
    	ll->data=-1;
    	return ll;
    }
    void listinsert(linklist L,int x,int i)
    {
    	linklist p,q;
    	int cnt=0;
    	q=L;
    	while(q&&cnt<i-1)//查找位序为i-1的结点 
    	{
    		q=q->next;
    		cnt++;
    	}
    	if(q==NULL||cnt!=i-1)// 所找结点不在L中
    	{
    		printf("插入位置异常\n");
    		exit(0);
    	}
    	else
    	{
    		p=(linklist)malloc(sizeof(linklist)); /*申请、填装结点*/
    		p->data = x; 
    		p->next = q->next;
    		q->next = p;
    		return ;
    	}
    }
    bool listdelete(linklist L,int i)
    {
    	linklist p,q;
    	int cnt=0;
    	q=L;
    	while(q&&cnt<i-1)
    	{
    		q=q->next;
    		cnt++;
    	}
    	if(q==NULL||cnt!=i-1||q->next==NULL)
    	{
    		printf("删除位置错误\n");
    		return false;
    	}
    	else
    	{
    		p=q->next;
            q->next=p->next;
    		free(p);
    		return true;
    	}
    }
    int main()
    {
    	linklist aa,bb;
    	int i=0,index;
    	aa=bb=listcreate();
    	printf("请输入多个数,以空格为区分,换行结束\n");
    	while(true)
    	{
    		int x;
    		scanf("%d",&x);
    		char ch=getchar();//读取空格
    		i++;
    		listinsert(aa,x,i);
    		if(ch=='\n')	break;//如果数字后的元素是换行符,就跳出循环
    	}
    	aa=bb;
    	printf("输入删除元素的位序:\n");
    	scanf("%d",&index);
    	if(listdelete(aa,index))	printf("删除成功\n");
    	aa=bb;
    	aa=aa->next;//头结点无意义,跳过头结点
    	while(aa)
    	{
    	printf("%d ",aa->data);
    	aa=aa->next;
    	}
    
    	return 0;
    }
    

    在这里插入图片描述

顺序存储和链式存储的优缺点:

  • 存储分配方式:顺序存储采用连续存储的单元进行存储,而链表采用一组任意存储单元进行存储。
  • 时间性能:
  1. 查找:顺序存储O(1) ,链表 O(n);
  2. 插入与删除:顺序存储O(n),链表 O(1);
  • 空间性能:顺序存储结构需要分配存储空间,链表不需要分配,元素个数不受限制。
发布了39 篇原创文章 · 获赞 1 · 访问量 579

猜你喜欢

转载自blog.csdn.net/qq_45249273/article/details/104004047