0
点赞
收藏
分享

微信扫一扫

【数据结构】线性表 顺序表(动态、静态分配,插入删除查找基本操作)解析+完整代码

修炼之士 2024-02-27 阅读 12

1.线性表的基本概念

  • 定义

  • 前驱、后继

  • 存储/物理结构

2.顺序表

2.1 顺序表的定义

  • 顺序表定义

  • 优点

  • 缺点

2.1.1 静态分配
//静态分配结构存储
#define MaxSize 10 //最大长度
typedef struct{
    int data[MaxSize]; //静态数组存放数据元素
    int length; //顺序表当前长度
}SqList; //顺序表类型定义

//静态分配初始化
void InitList(SqList &L){
    L.Length=0;
}
  • 如果数组存满怎么办?

2.1.2 动态分配
//动态分配结构存储
#define InitSize 100 //表长度的初始定义
typedef struct{
    ElemType *data; //指示动态分配数组的指针
    int MaxSize; //最大容量
    int length; //当前个数
}SeqList;

//动态分配初始化
void InitList(SeqList &L){
    L.data=(ElemType*)malloc(MaxSize*sizeof(ElemType));
    L.length=0;
    L.MaxSize=InitSize;
}

C动态分配语句

L.data=(ElemType*)malloc(sizeof(ElemType)*InitSize);
free(L.data);

C++动态分配语句

L.data=new ElemType[InitSize];
delete[]指针变量名;
或
delete 指针变量名;
  • 增加动态数组长度

    void IncreaseSize(SeqList &L,int len){
        int *p=L.data; //将表中数据存储到p中
        L.data=(int*)malloc((L.MaxSize+len)*sizeof(int)); //开辟新空间
        for(int i=0;i<L.length;i++)
        {
            L.data[i]=p[i]; //数据复制到新区域
        }
        L.MaxSize=L.MaxSize+len;
        free(p);
    }
    
  • 注:动态分配不是链式存储,同样顺序存储,只是空间大小可变。

2.2 顺序表的插入

  • 原理

    >

//在L的位序i处插入元素e
bool ListInsert(SqList &L,int i,int e){
    //判i范围是否有效
    if(i<1||i>L.length+1)return false;
    //判存储空间是否已满
    if(L.length>=MaxSize)return false;
    
    //将第i个元素及之后元素后移
    for(int j=L.length;j>=i;j--) 
    {
        L.data[j]=L.data[j-1]; //注意:位序和数组下标的关系,并从后面元素依次移动
    }
    L.data[i-1]=e;
    L.length++;
    return true;
}
  • 时间复杂度

2.3 顺序表的删除

  • 原理

//删除L中的第i个元素,并用返回
bool ListDelete(SqList &L,int i,ElemType &e){
    if(i<1||i>L.length)return false;
    
    e=L.data[i-1]; //被删元素给引用变量
    //被删元素后的元素依次后移
    for(int j=i;j<L.length;j++){
        L.data[j-1]=L.data[j];
    }
    L.length--;
    return true;
}
  • 时间复杂度

2.4 顺序表的查找

2.4.1 按位查找
ElemType GetElem(SqList L,int i){
    return L.data[i-1];
}
  • 时间复杂度:O(1)
2.4.2 按序查找
int LocateElem(SqList L,ElemType e){
    int i;
    for(i=0;i<L.length;i++)
    {
        if(L.data[i]==e)return i+1; //找到了返回位序
    }
    return 0; //没找到返回0
}
  • 时间复杂度:O(n)

*完整代码 顺序表静态存储

//顺序表 静态分配 线性表下标从0开始
#include<stdio.h>

#define ElemType int

//静态结构体
#define MaxSize 99
typedef struct {
	ElemType data[MaxSize];
	int length;
}SqList;

//初始化
void InitList(SqList &L)
{
	L.length = 0;
}

//求表长
int Length(SqList &L) 
{
	return L.length;
}

//按值查找
int LocateElem(SqList &L,ElemType e) 
{
	for (int i = 0; i < L.length; i++) 
	{
		if (L.data[i] == e) 
		{
			return i + 1;
		}
	}
	return 0;
}

//按位查找
int GetItem(SqList& L, int i) 
{
	return L.data[i-1]; //i是位序,而顺序表从0开始存的,所以i要-1
}

//插入操作
bool ListInsert(SqList& L, int i, ElemType e) 
{
	if (i<1 || i>L.length)return false;
	if (L.length >= MaxSize)return false;

	for (int j = L.length; j >= i; j--) 
	{
		L.data[j] = L.data[j - 1];
	}
	L.data[i-1] = e; 
	L.length++;
	return true;
}

//删除操作
bool ListDelete(SqList& L, int i, ElemType& e) 
{
	if (i<1 || i>L.length)return false;

	e = L.data[i-1];
	for (int j = i; j <L.length; j++) 
	{
		L.data[j-1] = L.data[j];
	}
	L.length--;
	return true;
}

//判空操作
bool Empty(SqList& L)
{
	if (L.length == 0)
		return true;
	else
		return false;
}

//销毁操作
void DestroyList(SqList &L)
{
	L.length = 0;
}

//输出
void PrintList(SqList& L) 
{
	for (int i = 0; i < L.length; i++)
	{
		printf("%d ", L.data[i]);
	}
	printf("\n");
}

int main()
{
	SqList L;
	InitList(L);
	//赋值
	for (int i = 0; i < 10; i++)
	{
		L.data[i] = i;
		L.length++;
	}
	PrintList(L);

	printf("插入:\n");
	int e = -1, pos = 4;
	ListInsert(L, pos , e);
	PrintList(L);

	printf("删除:\n");
	int a;
	ListDelete(L, pos, a);
	PrintList(L);
	printf("%d\n", a);

	printf("按值查找:\n");
	pos = LocateElem(L, 5);
	printf("%d\n", pos);

	printf("按位查找:\n");
	printf("%d", GetItem(L, 3));
}

请添加图片描述

*完整代码 顺序表动态存储

//顺序表 动态分配 
#include<stdio.h>
#include <stdlib.h>

#define ElemType int

//静态结构体
#define InitSize 2
typedef struct {
	ElemType *data;
	int length;
	int MaxSize;
}SeqList;

//初始化
void InitList(SeqList& L)
{
	L.data = (ElemType*)malloc(InitSize * sizeof(ElemType));
	L.length = 0;
	L.MaxSize = InitSize;
}

//增加动态数组长度
void IncreaseSize(SeqList& L, int len) {
	int* p = L.data; //将表中数据存储到p中
	L.data = (int*)malloc((L.MaxSize + len) * sizeof(int)); //开辟新空间
	for (int i = 0; i < L.length; i++)
	{
		L.data[i] = p[i]; //数据复制到新区域
	}
	L.MaxSize = L.MaxSize + len;
	free(p);
}

//求表长
int Length(SeqList& L)
{
	return L.length;
}

//按值查找
int LocateElem(SeqList& L, ElemType e)
{
	for (int i = 0; i < L.length; i++)
	{
		if (L.data[i] == e)
		{
			return i + 1;
		}
	}
	return 0;
}

//按位查找
int GetItem(SeqList& L, int i)
{
	return L.data[i - 1]; //i是位序,而顺序表从0开始存的,所以i要-1
}

//插入操作
bool ListInsert(SeqList& L, int i, ElemType e)
{
	if (i<1 || i>L.length)return false;
	if (L.length >= L.MaxSize)return false;

	for (int j = L.length; j >= i; j--)
	{
		L.data[j] = L.data[j - 1];
	}
	L.data[i - 1] = e; 
	L.length++;
	return true;
}

//删除操作
bool ListDelete(SeqList& L, int i, ElemType& e)
{
	if (i<1|| i>L.length)return false;

	e = L.data[i - 1];
	for (int j = i; j < L.length; j++)
	{
		L.data[j - 1] = L.data[j];
	}
	L.length--;
	return true;
}

//判空操作
bool Empty(SeqList& L)
{
	if (L.length == 0)
		return true;
	else
		return false;
}

//销毁操作
void DestroyList(SeqList& L)
{
	free(L.data);
	L.data = NULL; // 避免悬挂指针
	L.length = 0;
}

//输出
void PrintList(SeqList& L)
{
	for (int i = 0; i < L.length; i++)
	{
		printf("%d ", L.data[i]);
	}
	printf("\n");
}

int main()
{
	SeqList L;
	InitList(L);
	IncreaseSize(L, 9);

	//赋值
	for (int i = 0; i < 10; i++)
	{
		L.data[i] = i;
		L.length++;
	}
	PrintList(L);

	printf("插入:\n");
	int e = -1, pos = 5;
	ListInsert(L, pos, e);
	PrintList(L);

	printf("删除:\n");
	int a;
	ListDelete(L, pos, a);
	PrintList(L);
	printf("%d\n", a);

	printf("按值查找:\n");
	pos = LocateElem(L, 5);
	printf("%d\n", pos);

	printf("按位查找:\n");
	printf("%d", GetItem(L, 3));

	DestroyList(L);
}

举报

相关推荐

0 条评论