动态顺序表的基本接口

静态顺序表只适用于确定需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以,本篇中我们实现动态顺序表。

SeqList.h

#ifndef _SEQLIST_H_
#define _SEQLIST_H_


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<Windows.h>


typedef int SLDataType;

// 顺序表的动态存储 
typedef struct SeqList {
	SLDataType* array;  // 指向动态开辟的数组
	size_t size;       // 有效数据个数
	size_t capacity;   // 容量空间的大小
}SeqList;

// 基本增删查改接口 
void SeqListInit(SeqList* psl, size_t capacity);
void SeqListDestory(SeqList* psl);

void CheckCapacity(SeqList* psl);
void SeqListPushBack(SeqList* psl, SLDataType x);
void SeqListPopBack(SeqList* psl);
void SeqListPushFront(SeqList* psl, SLDataType x);
void SeqListPopFront(SeqList* psl);

int SeqListFind(SeqList* psl, SLDataType x);
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x);
void SeqListErase(SeqList* psl, size_t pos);
void SeqListRemoveFirst(SeqList* psl, SLDataType x);
void SeqListRemoveAll(SeqList* psl, SLDataType x);
void SeqListModify(SeqList* psl, size_t pos, SLDataType x);
void SeqListPrint(SeqList* psl);

void SeqListBubbleSort(SeqList* psl);
int SeqListBinaryFind(SeqList* psl, SLDataType x);



#endif /*_SEQLIST_H_*/


SeqList.c

#include"SeqList.h"


// 基本增删查改接口 
void SeqListInit(SeqList* psl, size_t capacity)  //创建
{
	psl->array = (SLDataType *)calloc(capacity,sizeof(SLDataType));
	psl->size = 0;
	psl->capacity = capacity;
}

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

void CheckCapacity(SeqList* psl) //检查满
{
	if (psl->size == psl->capacity)
	{
		psl->capacity *= 2;
		psl->array = (SLDataType *)realloc(psl->array, psl->capacity * sizeof(SLDataType));
	}
}

void SeqListPushBack(SeqList* psl, SLDataType x) //尾插
{
	CheckCapacity(psl);

	psl->array[psl->size] = x;
	psl->size++;
}

void SeqListPopBack(SeqList* psl) //尾删
{
	psl->size--;
}

void SeqListPushFront(SeqList* psl, SLDataType x) //头插
{
	CheckCapacity(psl);

	int i;
	for (i = psl->size - 1; i >= 0; i--)
	{
		psl->array[i + 1] = psl->array[i];
	}
	psl->array[0] = x;
	psl->size++;
}

void SeqListPopFront(SeqList* psl) //头删
{
	int i;
	for (i = 0; i < psl->size - 1; i++)
	{
		psl->array[i] = psl->array[i + 1];
	}
	psl->size--;
}

int SeqListFind(SeqList* psl, SLDataType x) //找
{
	int i;
	for (i = 0; i < psl->size; i++)
	{
		if (psl->array[i] == x)
		{
			return i;
		}
	}
	return -1;
}

void SeqListInsert(SeqList* psl, size_t pos, SLDataType x) //pos位后插x
{
	if (pos < 0 || pos >= psl->size)
	{
		return -1;
	}

	CheckCapacity(psl);

	int i;
	for (i = psl->size - 1; i >= pos; i--)
	{
		psl->array[i + 1] = psl->array[i];
	}
	psl->array[pos] = x;
	psl->size++;
}

void SeqListErase(SeqList* psl, size_t pos) //删除pos位的值
{
	if (pos < 0 || pos >= psl->size)
	{
		return -1;
	}

	int i;
	for (i = pos; i < psl->size - 1; i++)
	{
		psl->array[i] = psl->array[i + 1];
	}
	psl->size--;
}

void SeqListRemoveFirst(SeqList* psl, SLDataType x)//删掉指定值(第一个)的x
{
	if (SeqListFind(psl, x) != x)
	{
		SeqListErase(psl, SeqListFind(psl, x));
	}
}

#if 0
//删除所有的指定值x
void SeqListRemoveAll(SeqList* psl, SLDataType x)//方法1:空间O(1),O(n)
{
	int gap = 0;

	int i;
	for (i = 0; i < psl->size - gap; i++)
	{
		if (psl->array[i + gap] == x)
		{
			gap++;
			if (i + gap >= psl->capacity)  //避免极端情况下的数组最后一位越界
			{
				break;
			}
		}
		psl->array[i] = psl->array[i + gap];
	}
	psl->size -= gap;
}
#else
void SeqListRemoveAll(SeqList* psl, SLDataType x)//方法2:空间O(n),时间O(n)
{
	SLDataType *tmp = (SLDataType *)calloc(psl->capacity, sizeof(SLDataType));
	int i, j;

	for (i = 0, j = 0; i < psl->size; i++){
		if (psl->array[i] != x){
			tmp[j] = psl->array[i];
			j++;
		}
	}
	free(psl->array);
	psl->array = tmp;
	psl->size = j;
}
#endif

void SeqListModify(SeqList* psl, size_t pos, SLDataType x) //修改 
{
	if (pos >= 0 && pos < psl->size)
	{
		psl->array[pos] = x;
	}
}

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

void SeqListBubbleSort(SeqList* psl)
{
	int i, j;
	SLDataType tmp;
	for (i = 0; i < psl->size; i++)
	{
		for (j = 0; j < psl->size - i; j++)
		{
			if (psl->array[j] > psl->array[j + 1])
			{
				tmp = psl->array[j];
				psl->array[j] = psl->array[j + 1];
				psl->array[j + 1] = tmp;
			}
		}
	}
}

int SeqListBinaryFind(SeqList* psl, SLDataType x)
{
	SLDataType start = psl->array[0];
	SLDataType end = psl->array[psl->size - 1];
	SLDataType mid;

	while (start <= end)
	{
		mid = (start + end) / 2;
		if (x < mid)
		{
			end = mid - 1;
		}
		else if (x > mid)
		{
			start = start + 1;
		}
		else
		{
			return mid;
		}
	}
	return -1;
}

main.c

#include"SeqList.h"

int main()
{
	SeqList test;

	//顺序表的创建
	SeqListInit(&test, 15);
	//尾插
	SeqListPushBack(&test, 1);
	SeqListPushBack(&test, 2);
	SeqListPushBack(&test, 3);
	SeqListPushBack(&test, 4);
	SeqListPushBack(&test, 5);
	SeqListPushBack(&test, 6);
	SeqListPushBack(&test, 7);
	SeqListPushBack(&test, 8);
	SeqListPushBack(&test, 9);
	SeqListPushBack(&test, 10);
	SeqListPrint(&test);
	printf("\n");
	//尾删
	SeqListPopBack(&test);
	SeqListPopBack(&test);
	SeqListPrint(&test);
	printf("\n");
	//头删
	SeqListPopFront(&test);
	SeqListPopFront(&test);
	SeqListPopFront(&test);
	SeqListPrint(&test);
	printf("\n");
	//头插
	SeqListPushFront(&test, 11);
	SeqListPushFront(&test, 12);
	SeqListPushFront(&test, 13);
	SeqListPushFront(&test, 14);
	SeqListPushFront(&test, 15);
	SeqListPrint(&test);
	printf("\n");

	SeqListPopFront(&test);
	SeqListPopFront(&test);
	SeqListPrint(&test);
	printf("\n");
	//顺序表的查找
	int res1 = SeqListFind(&test, 5);
	if (res1 == -1)
	{
		printf("error\n");
	}
	else
	{
		printf("Find it! The pos is: %d\n", res1);
	}

	SeqListInsert(&test, 5, 100);
	SeqListPrint(&test);
	printf("\n");

	SeqListErase(&test, 5);
	SeqListPrint(&test);
	printf("\n");

	//为保证后面的删除函数的准确性
	SeqListPushFront(&test, 1);
	SeqListPushFront(&test, 1);
	SeqListPushFront(&test, 1);
	SeqListPushFront(&test, 1);
	SeqListPrint(&test);
	printf("\n");
	//删除第一个值为1的元素
	SeqListRemoveFirst(&test, 1);
	SeqListPrint(&test);
	printf("\n");
	//删除所有值为1的元素
	SeqListRemoveAll(&test, 1);
	SeqListPrint(&test);
	printf("\n");

	//将第pos位的值修改为x
	SeqListModify(&test, 1, 100);
	SeqListPrint(&test);
	printf("\n");
	//冒泡排序
	SeqListBubbleSort(&test);
	SeqListPrint(&test);
	printf("\n");
	//二分查找
	int res2 = SeqListBinaryFind(&test, 5);
	if (-1 == res2)
	{
		printf("error\n");
	}
	else
	{
		printf("Find it! The pos is: %d\n", res2);
	}
	printf("\n");




	SeqListDestory(&test);




	system("pause");
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值