数据结构学习篇(三)—— 顺序表的实现

顺序表的实现

 1.顺序表的定义与相关注意

        顺序表的逻辑结构下标从1开始依次向后增加,而存储结构是相当于数组般,从0开始往后进行存储,因此逻辑位序和物理位序相差1,如下图所示:

 其类型定义:

其中元素是以数组的方式存储的,也就是L.elem[ i ]的样式,而在线性表L中,是存储在一个内存块中的,其表示可如图显示 

 2.顺序表操作函数定义

添加操作进行在下标为i的位置插入一个元素图解:

 具体操作就是借用指针来进行操作,具体如下图所示:

 3.代码以及运行结果

test.c

#include "Operation.h"
int main()
{
	SqList L;
	int i;
	int e;
	//初始化
	InitList_Sq(&L);
	if (!InitList_Sq(&L))
	{
		printf("初始化错误");
			return -1;
	}


	// 插入数据
	for (i = 1; i <= 10; i++)
	{
		ListInsert(&L, i, i);
	}
	printf("输出顺序表内容:");
	// 打印数据
	ListPrint(L);


	// 查找数据
	printf("请输入查找的数据:");
	scanf("%d", &e);
	if (LocateElem(L, e)) 
	{
		printf("查找成功,元素下标为%d \n", LocateElem(L, e));
	}
	else {
		printf("查找失败!\n");
	}
	// 获取第i位置的元素内容
	printf("请输入查找元素下标:");
	scanf("%d", &i);
	if (GetElem(L, i, &e))
	{
		printf("查找到第%d个元素为%d \n", i, e);
	}
	else {
		printf("查找失败!\n");
	}

	// 删除数据
	printf("请输入要删除的元素下标:");
	scanf("%d", &i);
	if (ListDelete(&L, i, &e))
	{
		printf("删除成功,删除的元素为%d\n", e);
	}
	else {
		printf("删除失败!\n");
	}

	// 打印数据
	ListPrint(L);

	// 清空线性表
	ClearList(&L);
	// 打印数据
	ListPrint(L);

	// 销毁已存在的线性表
	DestroyList(&L);
	// 打印数据
	ListPrint(L);
	return 0;
}

头文件:Operation.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define INFEASIBLE -1

typedef int Status;
typedef int ElemType;

#define MAXSIZE 100
#define LISTINCREMENT 10

typedef struct
{
	ElemType* elem;
	int length;
}SqList; //定义顺序表类型

//初始化顺序表
Status InitList_Sq(SqList* L);
// 插入数据
Status ListInsert(SqList* L,int i,ElemType e);
// 打印数据
Status ListPrint(SqList L);
// 查找数据
Status LocateElem(SqList L,ElemType e);
// 获取第i位置的元素内容
Status GetElem(SqList L,int i, ElemType* e);
// 删除数据
Status ListDelete(SqList* L,int i,ElemType* e);
// 清空线性表
Status ClearList(SqList* L);
// 销毁已存在的线性表
Status DestroyList(SqList* L);
//判断错误问题
void QuestPrint(int Q);

对函数的实现Operation.c

#include "Operation.h"

//初始化顺序表
Status InitList_Sq(SqList* L) {
	L->elem = (ElemType*)malloc(sizeof(ElemType) * MAXSIZE);
	if (!L->elem) exit(OVERFLOW);
	L->length = 0;
	return OK;
}
// 插入数据
Status ListInsert(SqList* L, int i, ElemType e)
{
	int* Newbase;
	//判断i是否在线性表的长度范围内
	if (i >= 1 && i <= L->length + 1)
	{
		//判断线性表的长度是否还有内存,如果已经初始化的最大内存,自动扩存
		if (L->length >= MAXSIZE)
		{
			Newbase = (int*)malloc((MAXSIZE + LISTINCREMENT) * sizeof(int));
		}

		//定义两个指针变量,p取得elem数组中的i-1个位置,然后将i-1位置的元素往后移一个位置
		//即i-1位置的元素到i位置

		int* p, * q;
		p = &(L->elem[i - 1]);
		for (q = &(L->elem[L->length - 1]); q >= p; --q)
		{
			*(q + 1) = *q;    //将原来是q地址的元素放到q+1地址里头
		}
		//将e赋值到p的位置里
		*p = e;
		++L->length;
		return OK;
	}
	else { //i不在L的长度内
		return OVERFLOW;
	}
}
// 打印数据
Status ListPrint(SqList L)
{
	if (L.length) {
		//从0开始遍历elem数组,输出线性表长度length个元素
		for (int i = 0; i < L.length; i++)
		{
			printf("%d ", L.elem[i]);
		}
		printf("\n");
		return OK;
	}
	else {
		return INFEASIBLE;
	}
	
}
// 查找数据
Status LocateElem(SqList L, ElemType e)
{
	if (L.length)
	{
		int i = 0;
		for (i = 0; i < L.length; i++)
		{
			if (L.elem[i] == e) {
				return i;
				break;
			}
		}
		return FALSE;
		
	}
	else
	{
		return INFEASIBLE;
	}
}
// 获取第i位置的元素内容
Status GetElem(SqList L, int i, ElemType* e)
{
	if (i >= 0 && i < L.length) {
		*e = L.elem[i];
		return TRUE;
	}
	else {
		return FALSE;
		return OVERFLOW;
	}
		
}
// 删除数据
Status ListDelete(SqList* L, int i, ElemType* e)
{
	
	if (i >= 0 && i <= L->length) {
		*e = L->elem[i - 1];
		int* p;
		//p在最后一个地址之前,将后面元素赋给前面一个地址,依次往后移
		for (p = &(L->elem[i - 1]); p <= &(L->elem[L->length - 1]); ++p)
		{
			*p = *(p + 1);  //将后面的元素都往前挪一个地址
		}
		L->length = L->length - 1;
		return TRUE;
	}
	else {
		return FALSE;
		return OVERFLOW;
	}
}
// 清空线性表
Status ClearList(SqList* L)
{
	L->length = 0;
	printf("已经清空线性表,当前长度为0!\n");
	return OK;
}
// 销毁已存在的线性表
Status DestroyList(SqList* L)
{
	if (L->elem)
	{
		free(L->elem);
		printf("销毁成功,当前线性表元素为0!\n");
		return OK;
	}
	else {
		return INFEASIBLE;
	}
}
//判断错误问题
void QuestPrint(int Q)
{
	if (Q == 0)
	{
		printf("出错了!");
	}
	if (Q == -1)
	{
		printf("线性表为空,或者不存在!");
	}
	if (Q == -2)
	{
		printf("不在查询范围内!");
	}
}

运行结果:

         顺序表的实现相对比较简单,跟数组的操作类似,差不多就只有插入的操作有些许难理解,其他都比较简单。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值