顺序表的动态内存实现

线性表的顺序存储结构就是,把线性表中的所有元素按照其逻辑顺序依次存储在计算机存储器中指定存储位置开始的一块连续的存储空间中。因此,线性表的顺序存储结构是利用数组来实现的,数组的基本类型就是线性表中元素的类型。

实现一个顺序表首先要制定一个顺序表的长度和存放数据的地址,还必须有已经存放的数据数量和总数量,顺序表的实现可以是静态的也可以是动态的,不过静态比较浪费内存,所以采用动态内存分配来实现顺序表


实现的顺序表有一下几个功能:

1.从后面增加

2.从后面删除

3.从前面增加

4.从前面删除

5.在顺序表里相应位置插入相应元素

6.在顺序表里查找相应元素

7.在顺序表里删除最先出现的对应元素

8.对顺序表进行逆序

9.深度冒泡排序

10.二分查找

接下来用代码来实现

seqlist.h

#ifndef _SEQLIST_H_
#define _SEQLIST_H_


#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define INIT_SZ 2	//初始化内存大小
#define INIT_INC 1	//动态增长大小
#define MAX 100	//顺序表的长度

typedef int DataType; //将结构体的类型重命名

typedef struct seqlist 
{
	DataType *data;
	int sz; 
	int capacity;
}seqlist,*pseqlist;

void checkcapacity(pseqlist ps);//检查内存
void InitSeqList(pseqlist ps);//顺序表初始化
void Destoryseqlist(pseqlist ps);//销毁队列
void PushBack(pseqlist ps, DataType d);//从后面增加
void Printseqlist(const pseqlist ps);//打印顺序表
void PopBack(pseqlist ps);//从后面删除
void PushFront(pseqlist ps, DataType d);//从前面增加
void PopFront(pseqlist ps);//从后面删除
void Insert(pseqlist ps, int pos, DataType d);//在顺序表指定位置插入元素
int Find(const pseqlist ps, DataType d);//在顺序表里查找相应元素
void Remove(pseqlist ps, DataType d);//在顺序表里删除最先出现的对应元素
void Reverseseqlist(pseqlist ps);//对顺序表进行逆序
void Sortseqlist(pseqlist ps);//深度冒泡排序
int BinarySearch(pseqlist ps, DataType d);//二分查找
void Findresult(pseqlist ps, DataType d);//打印查找的结果
void BinarySearchresult(pseqlist ps, DataType d);//打赢二分查找后的结果




#endif   //_SEQLIST_H_

seqlist.c

#include "sqlist.h"

void InitSeqList(pseqlist ps)	//初始化结构体成员
{
	assert(ps);
	ps->data = (DataType *)malloc(sizeof(seqlist)*INIT_SZ);		//给结构体里存放数据的动态开辟大小为2的内存
	if(ps->data != NULL)
	{
		ps->sz = 0;
		ps->capacity = INIT_SZ;//总容量定义为2
	}
}

void Destoryseqlist(pseqlist ps)	//回收开辟的动态内存
{
	assert(ps);
	if(ps->data != NULL)
	{
		free(ps->data);
		ps->data = NULL;//将开辟的指针的赋为空指针,防止成为野指针被使用
	}
}

void checkcapacity(pseqlist ps)//检查总容量,不够就扩容
{
	assert(ps);
	if(ps->sz == ps->capacity)//当容量满了时,每次容量扩增1个结构体大小
	{
		DataType *str = (DataType *)realloc(ps->data,sizeof(seqlist)*(ps->capacity+INIT_INC));
		if(str != NULL)
		{
			ps->data = str;
			ps->capacity += INIT_INC;
			printf("添加成功\n");
			return;
		}
		exit(EXIT_FAILURE);
	}
}
void PushBack(pseqlist ps, DataType d)//在顺序表的后面插入元素
{
	assert(ps);
	checkcapacity(ps);//先检查内存容量,不够先进行扩容
	if(ps->sz != MAX)//结构体的最大容量为100
	{
		ps->data[ps->sz] = d;
		ps->sz++;
		return;
	}
	exit(EXIT_FAILURE);
}


void Printseqlist(const pseqlist ps)
{
	int i = 0;
	assert(ps);
	for(i=0; i<ps->sz; i++)
	{
		printf("%d ",ps->data[i]);
	}
	printf("\n");
}

void PopBack(pseqlist ps)//后删
{
	assert(ps);
	if(ps->data != NULL)
	{
		ps->sz--;//直接把已存数量减一就把最后的删除了
		return;
	}
	exit(EXIT_FAILURE);
}

void PushFront(pseqlist ps, DataType d)//从顺序表的前面插入元素
{
	int i = 0;
	assert(ps);
	checkcapacity(ps);//进来先检查容量
	if(ps->sz != MAX)
	{
		for(i=ps->sz; i>=0; i--)
		{
			ps->data[i] = ps->data[i-1];
		}
		ps->sz++;
		ps->data[0] = d;
	}
}

void PopFront(pseqlist ps)//从顺序表的前面删除
{
	int i = 0;
	assert(ps);
	if(ps->data != NULL)
	{
		for(i=0; i<ps->sz; i++)
			ps->data[i] = ps->data[i+1];
		ps->sz--;
		return;
	}
	exit(EXIT_FAILURE);
}

void Insert(pseqlist ps, int pos, DataType d) //在下标前面插入d
{
	int i = 0;
	checkcapacity(ps);//插入也是增加元素个数,所以进来先判断容量大小
	assert(ps);
	if((ps->data != NULL) || (ps->sz != MAX))
	{
		for(i=ps->sz; i>=pos; i--)
		{
			ps->data[i] = ps->data[i-1];
		}
		ps->data[pos] = d;
		ps->sz++;
		return;
	}
	exit(EXIT_FAILURE);
}

int Find(const pseqlist ps, DataType d)//在顺序表里查找元素d
{
	int i = 0;
	assert(ps);
	for(i=0; i<ps->sz; i++)//遍历查找
	{
		if(ps->data[i] == d)
			return i;
	}
	return -1;
}

void Findresult(pseqlist ps,DataType d)	//打印查找的数的下标
{
	int ret = 0;
	ret = Find(ps,d);
	printf("%d\n",ret);
}

void Remove(pseqlist ps, DataType d)//删除顺序表里首先出现d的元素
{
	int i = 0;
	int ret = 0;
	assert(ps);
	ret = Find(ps,d);//用已经查找的函数返回值去接收
	if(ret == -1)
		return;
	for(i=ret; i<ps->sz; i++)
	{
		ps->data[i] = ps->data[i+1];	
	}
	ps->sz--;
}

void Reverseseqlist(pseqlist ps)//将顺序表逆序
{
	int left = 0;
	int right = ps->sz-1;
	assert(ps);
	while(left<=right)
	{
		int tmp = ps->data[left];
		ps->data[left] = ps->data[right];
		ps->data[right] = tmp;
		left++;
		right--;
	}
}

void Sortseqlist(pseqlist ps)//对顺序表进行深度冒泡排序
{
	int i = 0;
	int j = 0;
	assert(ps);
	for(i=0; i<ps->sz-1; i++)
	{
		for(j=0; j<ps->sz-i-1; j++)
		{
			if(ps->data[j] > ps->data[j+1])
			{
				int tmp = ps->data[j];
				ps->data[j] = ps->data[j+1];
				ps->data[j+1] = tmp;
			}
		}
	}
}

int BinarySearch(pseqlist ps, DataType d)//对顺序表进行二分查找
{
	int left = 0;
	int right = ps->sz-1;
	assert(ps);
	Sortseqlist(ps);//先进行冒泡排序,保证二分查找的有效性
	while(left<=right)
	{
		int mid = left-(left-right)/2;
		if(ps->data[mid] < d)
		{
			left = mid+1;
		}
		else if(ps->data[mid] > d)
		{
			right = mid-1;
		}
		else
		{
			return mid;
		}
	}
	return -1;
	
}

void BinarySearchresult(pseqlist ps, DataType d)	//打印查找的数的下标
{
	int ret = 0;
	ret = BinarySearch(ps, d);
	printf("%d\n",ret);
}


test.c

#include "sqlist.h"

void test()
{
	seqlist mylist;
	InitSeqList(&mylist);
	PushBack(&mylist,1);
	PushBack(&mylist,2);
	PushBack(&mylist,3);
	PushBack(&mylist,4);
	PushBack(&mylist,5);
	Printseqlist(&mylist);
	PopBack(&mylist);
	Printseqlist(&mylist);
	PushFront(&mylist,5);
	Printseqlist(&mylist);
	PopFront(&mylist);
	Printseqlist(&mylist);
	Insert(&mylist,2,6);
	Printseqlist(&mylist);
	Findresult(&mylist,6);
	Remove(&mylist,6);
	Printseqlist(&mylist);
	Reverseseqlist(&mylist);
	Printseqlist(&mylist);
	Sortseqlist(&mylist);
	Printseqlist(&mylist);
	BinarySearch(&mylist,3);
	BinarySearchresult(&mylist,3);
	Destoryseqlist(&mylist);//在使用完顺序表之后一定要使用Destoryseqlist函数

}

int main()
{
	test();	//测试用例
	system("pause");
	return 0;
}



发布了43 篇原创文章 · 获赞 47 · 访问量 3万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章