欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

DS顺序表的概念及动态顺序表接口的实现

程序员文章站 2024-03-20 13:51:04
...

顺序表

概念:
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构。

分类:
1,静态顺序表:使用定长数组存储。
2,动态顺序表:使用动态开辟的数组存储。(malloc,calloc,realloc)

由于静态顺序表只适用于已经知道要存储多少数据的情况,所以现实生活中一般都是使用动态顺序表,动态顺序表的实现如下

对所有接口的声明:seqlist.h

seqlist.h
#ifndef _SEQLIST_H_
#define _SEQLIST_H_

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
#include<malloc.h>
#include<windows.h>
#pragma warning (disable:4996)

typedef int SLDataType;

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

//顺序表的初始化
void SeqListInit(SeqList* psl, int capacity);
//顺序表的摧毁
void SeqListDestory(SeqList* psl);
//检查顺序表是否已满,满了进行扩容
void CheckCapacity(SeqList* psl);
//顺序表后插一个x
void SeqListPushBack(SeqList* psl, SLDataType x);
//顺序表后删一个值
void SeqListPopBack(SeqList* psl);
//顺序表前插一个数x
void SeqListPushFront(SeqList* psl, SLDataType x);
//顺序表前删一个数x
void SeqListPopFront(SeqList* psl);
//顺序表的查找,找到x数字并返回其下标
int SeqListFind(SeqList* psl, SLDataType x);
//在指定的pos位置进行插入一个数x
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x);
//删除pos位置的值
void SeqListErase(SeqList* psl, size_t pos);
//移除第一个x的值
void SeqListRemove(SeqList* psl, SLDataType x);
//将pos位置的值修改为x
void SeqListModify(SeqList* psl, size_t pos, SLDataType x);
//顺序表的打印
void SeqListPrint(SeqList* psl);
//顺序表的排序
void SeqListBubbleSort(SeqList* psl);
//顺序表的二分查找
int SeqListBinaryFind(SeqList* psl, SLDataType x);
//移除所有的数字x
void SeqListRemoveAll(SeqList* psl, SLDataType x);

#endif

对所有接口的实现:seqlist.c
实现详情参照注释

seqlist.c
#include"seqlist.h"

//顺序表的初始化
void SeqListInit(SeqList *psl, int capacity)
{
	assert(psl);
	psl->array = (SLDataType *)calloc(capacity, sizeof(SLDataType));//申请动态内存空间
	psl->size = 0;
	psl->capacity = capacity;
}

//顺序表的摧毁***********************************************************************************
void SeqListDestory(SeqList* psl)
{
	assert(psl);
	if (psl->array)//防止重复释放
	{
		free(psl->array);
		psl->array = NULL;
		psl->size = 0;
		psl->capacity = 0;
	}
}

//检查顺序表是否已满,满了进行扩容**********************************************************************
void CheckCapacity(SeqList* psl)
{
	if (psl->size == psl->capacity)
	{
		psl->capacity *= 2;
		SLDataType *tmp = (SLDataType *)realloc(psl->array, psl->capacity*sizeof(SLDataType));
		psl->array = tmp;
		printf("扩容成功\n");
		assert(psl->array);
	}
}

//顺序表后插一个x*****************************************************************************************
void SeqListPushBack(SeqList* psl, SLDataType x)//后插一个x
{
	assert(psl);
	CheckCapacity(psl);
	psl->array[psl->size] = x;
	psl->size++;
}

//顺序表后删一个值******************************************************************************************
void SeqListPopBack(SeqList* psl)//后删一个数
{
	psl->size--;
}

//顺序表前插一个数x********************************************************************************************
void SeqListPushFront(SeqList* psl, SLDataType x)//前插一个数x(将所有的数向后移动一位再插入要求的数)
{
	assert(psl);
	CheckCapacity(psl);
	int i = 0;
	for (i = psl->size-1; i >= 0; i--)
	{
		psl->array[i + 1] = psl->array[i];
	}
	psl->array[0] = x;
	psl->size++;
}

//顺序表前删一个数x*************************************************************************************
void SeqListPopFront(SeqList* psl)//前删一个数(用后一个数来覆盖前一个数)
{
	assert(psl);
	CheckCapacity(psl);
	int i = 0;
	for (i = 0; i < psl->size-1; i++)
	{
		psl->array[i] = psl->array[i + 1];
	}
	psl->size--;
}

//顺序表的查找,找到x数字并返回其下标************************************************************************
int SeqListFind(SeqList* psl, SLDataType x)//找到x数字并返回其下标
{
	assert(psl);
	int i = 0;
	for (i = 0; i < psl->size; i++)
	{
		if (psl->array[i] == x)
		{
			return i;
		}
	}
	return -1;
}

//在指定的pos位置进行插入一个数x***************************************************************************
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x)
{
	assert(psl);
	CheckCapacity(psl);
	int i = 0;
	for (i = psl->size - 1; i >= pos; i--)
	{
		psl->array[i + 1] = psl->array[i];
	}
	psl->array[pos] = x;
	psl->size++;
}

//删除pos位置的值************************************************************************************************
void SeqListErase(SeqList* psl, size_t pos)
{
	assert(psl);
	CheckCapacity(psl);
	int i = 0;
	for (i = pos; i < psl->size - 1; i++)
	{
		psl->array[i] = psl->array[i + 1];
	}
	psl->size--;
}

//移除第一个x的值***************************************************************************************
void SeqListRemove(SeqList* psl, SLDataType x)
{
	assert(psl);
	SeqListErase(psl, SeqListFind(psl, x));
}

//将pos位置的值修改为x*******************************************************************************************
void SeqListModify(SeqList* psl, size_t pos, SLDataType x)
{
	assert(psl);
	psl->array[pos] = x;
}

//顺序表的打印*******************************************************************************************
void SeqListPrint(SeqList* psl)
{
	int i = 0;
	for (i = 0; i < psl->size; i++)
	{
		printf("%d ", psl->array[i]);
	}
	putchar('\n');
}

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

//顺序表的二分查找*******************************************************************************************
int SeqListBinaryFind(SeqList* psl, SLDataType x)
{
	int start = 0;
	int end = psl->size - 1;
	while (start <= end)
	{
		int mid = (start + end) / 2;
		if (x>psl->array[mid])
		{
			start = mid + 1;
		}
		else if (x<psl->array[mid])
		{
			end = mid - 1;
		}
		else
		{
			printf("找到了%d的下标为%d \n",x, mid);
			return mid;
		}
	}
}

//移除所有的数字x*******************************************************************************************
void SeqListRemoveAll(SeqList* psl, SLDataType x)
{
	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;
}


void _SeqListRemoveAll(SeqList* psl, SLDataType x)
{
	int i, gap = 0;
	for (i = 0; i < psl->size; i++)
	{
		if (psl->array[i] == x)
		{
			gap++;
		}
		else
		{
			psl->array[i - gap] = psl->array[i];
		}
	}
	psl->size -= gap;
}

测试函数main函数:main.c

main.c
#include"seqlist.h"

int main()
{
	SeqList test;
	SeqListInit(&test, 3);
	SeqListPushBack(&test, 1);
	SeqListPushBack(&test, 6);
	SeqListPushBack(&test, 3);
	SeqListPushBack(&test, 4);
	SeqListPushBack(&test, 4);
	SeqListPushBack(&test, 2);
	SeqListPushBack(&test, 4);
	SeqListPushBack(&test, 8);
	SeqListPushBack(&test, 9);
	//SeqListRemoveAll(&test, 4);
	SeqListBubbleSort(&test);
	//SeqListBinaryFind(&test, 1);
	//int i=SeqListFind(&test, 8);
	//printf("%d ", i);
	//SeqListInsert(&test, 3,10);
	//SeqListErase(&test, 3);
	//SeqListPopFront(&test);
	//SeqListPushFront(&test, 10);
	SeqListPrint(&test);
	SeqListDestory(&test);
	system("pause");
	return 0;
}