动态顺序表

简单概要:

                    1> 定义一个结构体,结构体存放顺序表中成员的相关信息,其中结构体中定义一个指针,指向动态开辟的空间,使用时定一个结构体变量,这个变量通过->操作解引用顺序表中的成员。

                    2> 初始化、删除顺序表。

                    3> 增删改查操作的实现。

                    4> 使用冒泡排序和选择排序给顺序表成员排序;使用二分查找查找顺序中的成员。

                    5> 顺序表的打印。

具体实现如下:

 1.实现的函数定义在头文件中SeqList.h

#pragma once  //防止头文件被重复使用
              // #ifndef  endif同理

//数据结构是抽象类型
//数据本身不仅仅是数字

typedef int DataType;

#define INIT_CAPACITY (2)

typedef struct SeqList
{
	DataType* array;
	int capacity;  //当前容量
	int size;     //1.保存顺序表里已经存了的数据个数
	              //2.当前可用下标
}SeqList;

//接口 (函数)
//初始化、销毁、
//增、删、查、改

//初始化(函数设计)
void SeqListInit(SeqList* pSeq);

//销毁
void SeqListDestroy(SeqList* pSeq);

//扩容
static void ExpandIfRequired(SeqList* pSeq);

//增
//尾插(尽量和C++的 STL统一)
void SeqListPushBack(SeqList* pSeq, DataType data);

//头插
void SeqListPushFront(SeqList* pSeq, DataType data);

//中间插入
void SeqListInsert(SeqList* pSeq, int pos, DataType data);

//删
//尾删
void SeqListPopBack(SeqList* pSeq);

//头删
void SeqListTopFront(SeqList* pSeq);

//中间删
void SeqListErase(SeqList* pSeq, int pos);

//删除所有遇到的data
void SeqListRemoveAll(SeqList* pSeq, DataType data);

//查找
int SeqListFind(SeqList* pSeq, DataType data);

//修改
void SeqListRevise(SeqList* pSeq, int pos, DataType data);

//传指针减少空间,不改变值
void SeqListPrint(const SeqList* pSeq);

//冒泡排序
void SeqListBubbleSort(SeqList* pSeq);

//选择排序
void SeqListSelectSort(SeqList* pSeq);

//二分查找
int SeqListTwoPoint(SeqList* pSeq, DataType data);

 2. 实现各种函数SeqList.c

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "SeqList.h"

//初始化(函数设计)
void SeqListInit(SeqList* pSeq)
{
	//1.初始化 size
	//2.可能需要去把容器空间清空下
	assert(pSeq != NULL);
	//2.if(SeqList == NULL)
	//{}
	pSeq->capacity = INIT_CAPACITY;
	pSeq->array = (DataType*)malloc(sizeof(DataType)* pSeq->capacity);
	pSeq->size = 0;
}

//销毁
void SeqListDestroy(SeqList* pSeq)
{
	free(pSeq->array);
	pSeq->capacity = 0;
	pSeq->size = 0;
	pSeq->array = NULL;
}

//扩容
static void ExpandIfRequired(SeqList* pSeq)
{
	//扩容条件
	if (pSeq->size < pSeq->capacity)
	{
		//没满
		return;
	}
	pSeq->capacity *= 2;
	//1.申请新空间
	DataType* newArray = (DataType*)malloc(sizeof(DataType)*pSeq->capacity);
	//2.数据搬移
	for (int i = 0; i < pSeq->size; ++i)
	{
		newArray[i] = pSeq->array[i];
	}
	//3.释放老空间,关联新空间
	free(pSeq->array);
	pSeq->array = newArray;
}

//增
//尾插(尽量和C++的 STL统一)
void SeqListPushBack(SeqList* pSeq, DataType data)
{
	assert(pSeq != NULL);
	//特殊情况
	ExpandIfRequired(pSeq);
	//通常情况
	pSeq->array[pSeq->size] = data;
	++pSeq->size;
}

//头插
void SeqListPushFront(SeqList* pSeq, DataType data)
{
	assert(pSeq != NULL);
	//特殊情况
	ExpandIfRequired(pSeq);
	//通常情况
	//i代表位置
	for (int i = pSeq->size; i > 0; --i)
	{
		pSeq->array[i] = pSeq->array[i - 1];
	}
	/*
	//i代表数据
	for (int i = pSeq->size - 1; i >= 0; --i)
	{
	pSeq->array[i + 1] = pSeq->array[i];
	}
	*/
	//插入
	pSeq->array[0] = data;
	++pSeq->size;
}

//中间插入
void SeqListInsert(SeqList* pSeq, int pos, DataType data)
{
	assert(pSeq != NULL);
	assert(pos >= 0 && pos <= pSeq->size);
	//特殊情况
	ExpandIfRequired(pSeq);
	//通常情况
	for (int i = pSeq->size; i > pos; --i)
	{
		pSeq->array[i] = pSeq->array[i - 1];
	}
	//插入
	pSeq->array[pos] = data;
	++pSeq->size;
}

//删
//尾删
void SeqListPopBack(SeqList* pSeq)
{
	assert(pSeq != NULL);
	//特殊情况
	if (pSeq->size <= 0)
	{
		printf("没有数据");
		return;
	}
	//通常情况
	--pSeq->size;
}

//头删
void SeqListTopFront(SeqList* pSeq)
{
	assert(pSeq != NULL);
	//特殊情况
	if (pSeq->size <= 0)
	{
		printf("没有数据\n");
		return;
	}
	//通常情况
	for (int i = 1; i < pSeq->size; ++i)
	{
		pSeq->array[i - 1] = pSeq->array[i];
	}
	--pSeq->size;
}

//中间删
void SeqListErase(SeqList* pSeq, int pos)
{
	assert(pSeq != NULL);
	assert(pos >= 0 && pos < pSeq->size);
	//特殊情况
	ExpandIfRequired(pSeq);
	//数据搬移
	for (int i = pos; i < pSeq->size - 1; ++i)
	{
		pSeq->array[i] = pSeq->array[i + 1];
	}
	--pSeq->size;
}

//查找,找到了返回下标,没找到返回-1;
int SeqListFind(SeqList* pSeq, DataType data)
{
	assert(pSeq != NULL);
	for (int i = 0; i < pSeq->size; ++i)
	{
		if (pSeq->array[i] == data)
		{
			return i;
		}
	}
	return -1;
}

//删除所有遇到的data
void SeqListRemoveAll(SeqList* pSeq, DataType data)
{
	assert(pSeq!=NULL);
#if 0
	//简单方法时间复杂度位O(n^2)
	int pos;
	while ((pos = SeqListFind(pSeq, data)) != -1)
	{
		SeqListErase(pSeq, pos);
	}
	//开辟空间存储空间复杂度位O(n)
	DataType* tempArray = (DataType*)malloc(
		sizeof(DataType)*pSeq->size);
	assert(tempArray != NULL);
	int j = 0;
	//将不是data的数存放在新开辟的空间里
	for (int i = 0; i < pSeq->size; ++i)
	{
		if (pSeq->array[i] != data)
		{
			tempArray[j++] = pSeq->array[i];
		}
	}
	for (int i = 0; i < j; ++i)
	{
		pSeq->array[i] = tempArray[i];
	}
	pSeq->size = j;
#endif
	//时间复杂度和空间复杂度都为O(n)
	int j = 0;
	for (int i = 0; i < pSeq->size; ++i)
	{
		if (pSeq->array[i] != data)
		{
			pSeq->array[j++] = pSeq->array[i];
		}
	}
	pSeq->size = j;
}

//修改
void SeqListRevise(SeqList* pSeq, int pos, DataType data)
{
	assert(pSeq != NULL);
	assert(pos >= 0 && pos <= pSeq->size - 1);
	pSeq->array[pos] = data;
}

//传指针减少空间,不改变值
void SeqListPrint(const SeqList* pSeq)
{
	assert(pSeq != NULL);

	for (int i = 0; i < pSeq->size; ++i)
	{
		printf("%d", pSeq->array[i]);
	}
	printf("\n");
}

static Swap(DataType* x,DataType* y)
{
	DataType tmp = *x;
	*x = *y;
	*y = tmp;
}

//冒泡排序
void SeqListBubbleSort(SeqList* pSeq)
{
	assert(pSeq != NULL);
	for (int i = 0; i < pSeq->size; ++i)
	{
		int count = 0;
		for (int j = 0; j < pSeq->size - 1 - i; ++j)
		{
			if (pSeq->array[j] > pSeq->array[j + 1])
			{
				Swap(pSeq->array + j, pSeq->array + j + 1);
				count = 1;
			}
		}
		if (count == 0)
		{
			break;
		}
	}
}

//选择排序
void SeqListSelectSort(SeqList* pSeq)
{
	assert(pSeq != NULL);
	int min = 0;
	int max = pSeq->size-1;
	while (min < max)
	{
		int minSpace = min;
		int maxSpace = max;
		for (int i = min; i < max; ++i)
		{
			if (pSeq->array[i] < pSeq->array[min])
			{
				min = i;
			}
			if (pSeq->array[i]>pSeq->array[max])
			{
				max = i;
			}
		}
		Swap(pSeq->array + min, pSeq->array + minSpace);
		Swap(pSeq->array + max, pSeq->array + maxSpace);
		++min;
		--max;
	}
}

//二分查找
int SeqListTwoPoint(SeqList* pSeq,DataType data)
{
	assert(pSeq!= NULL);
	int left = 0;
	int right = pSeq->size;
	while (left < right)
	{
		int mid = (left + right) / 2;
		if (pSeq->array[mid] == data)
		{
			return mid;
		}
		else if (pSeq->array[mid] < data)
		{
			left = mid + 1;
		}
		else
		{
			right = mid;
		}
	}
	return -1;
}

  3. 打印相关函数Main.c

#include "SeqList.h"
#include <stdio.h>
#include <stdlib.h>

void Test()
{
	SeqList seqList;
	SeqListInit(&seqList); //1.seqList 2.&seqList  
	//传第二个1.指针空间小 2.修改里面的值
	//尾插
	SeqListPushBack(&seqList, 1);
	SeqListPushBack(&seqList, 3);
	SeqListPushBack(&seqList, 4);
	SeqListPushBack(&seqList, 2);
	SeqListPushBack(&seqList, 5);
	SeqListPushBack(&seqList, 2);
	SeqListPrint(&seqList);
	//头插
	SeqListPushFront(&seqList, 6);
	SeqListPrint(&seqList);
	//中间插
	SeqListInsert(&seqList, 3, 7);
	SeqListPrint(&seqList);
	//尾删
	SeqListPopBack(&seqList);
	SeqListPrint(&seqList);
	//头删
	SeqListTopFront(&seqList);
	SeqListPrint(&seqList);
	//中间删
	SeqListErase(&seqList, 3);
	SeqListPrint(&seqList);
	//查找
	int c = SeqListFind(&seqList, 2);
	printf("%d\n", c);
	//删除遇到的所有data
	SeqListRemoveAll(&seqList, 2);
	SeqListPrint(&seqList);
	//修改
	SeqListRevise(&seqList, 2, 9);
	SeqListPrint(&seqList);
	//冒泡
	SeqListBubbleSort(&seqList);
	SeqListPrint(&seqList);
	//二分查找
	int a = SeqListTwoPoint(&seqList, 5);
	printf("%d\n", a);
	//选择排序
	SeqListSelectSort(&seqList);
	SeqListPrint(&seqList);
	//二分查找
	int b = SeqListTwoPoint(&seqList, 5);
	printf("%d\n", b);
	//销毁
	SeqListDestroy(&seqList);
}

int main()
{
	Test();
	system("pause");
	return 0;
}

代码实现: 执行结果按Main.c执行

                    

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值