順序表的動態內存實現

線性表的順序存儲結構就是,把線性表中的所有元素按照其邏輯順序依次存儲在計算機存儲器中指定存儲位置開始的一塊連續的存儲空間中。因此,線性表的順序存儲結構是利用數組來實現的,數組的基本類型就是線性表中元素的類型。

實現一個順序表首先要制定一個順序表的長度和存放數據的地址,還必須有已經存放的數據數量和總數量,順序表的實現可以是靜態的也可以是動態的,不過靜態比較浪費內存,所以採用動態內存分配來實現順序表


實現的順序表有一下幾個功能:

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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章