1. 程式人生 > >【資料結構】順序表及其各個介面的實現

【資料結構】順序表及其各個介面的實現

在聊順序表之前,我們先來說一下線性表。

什麼是線性表呢?

線性表是n個具有相同特性的資料元素的有限序列。線性表是一種在實際中廣泛使用的資料結構,常見的線性表有:順序表,連結串列,棧,佇列,字串....

線性表在邏輯上是線性結構,也就是說是連續的一條直線。但在物理結構上並不一定是連續的,線性表在物理上儲存時,通常是以陣列和鏈式結構的形式儲存。如下圖所示:

 由上可知,其實順序表是一個線性表。

 

順序表是用一段實體地址連續儲存單元依次儲存資料元素的線性結構,- -般情況下采用陣列儲存。在陣列上完成資料的增刪查改。
           順序表一般可以分為:
                 1.靜態順序表:使用定長陣列儲存。
                 2.動態順序表:使用動態開闢的陣列儲存。

 //順序表的靜態儲存
      #define N 100

      typedef int SLDataType;

      typedef struct Seqlist

      { 

      SLDataType array[N]; //定長陣列

      size_ t   size ;  //有效資料的個數 

       }SeqList;

      //順序表的動態儲存

      typedef struct SeqList

      {

      SLDataType* array;  //指向動態開闢的陣列

      size_ t size ; //有效資料個數

      size_ t capicity ;  //容量空間的大小

      } Seqlist ;
 

介面實現:
          靜態順序表只適用於確定知道需要存多少資料的場景。靜態順序表的定長陣列導致N定大了,空間開多了浪費,開少了不夠用。所以現實中基本都是使用動態順序表,根據需要動態的分配空間大小,所以下面我們實現動態順序表。

Seqlist.h

#pragma once//windows vs

#ifndef _SEQLIST_H_//vs+gcc
#define _SEQLIST_H_

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <assert.h>
////靜態順序表
//#define N 10
//typedef int SLDateType;
//struct SeqList
//{
//	SLDateType _a[N];//陣列
//	size_t _size;//有多少個有效資料
//};
//void SeqListInit(SeqList*psl);//初始化
//void SeqListDestory(SeqList*psl);//銷燬
//
//void SeqListPushBack(SeqList*psl, SLDateType x);//尾插
//void SeqListPopBack(SeqList*psl);//頭插
//void SeqListPushFront(SeqList*psl, SLDateType x);//尾刪
//void SeqListPopFront(SeqList*psl);//頭刪
//
//void SeqListInsert(SeqList*psl,size_t pos, SLDateType x);//中間插入
//void SeqListErase(SeqList*psl, size_t pos, SLDateType x);//給下標,刪除下標處的東西
//void SeqListRemove(SeqList*psl, size_t pos, SLDateType x);//給一個x,刪除它

//動態順序表

typedef int SLDateType;
typedef struct SeqList
{
	SLDateType* _a;   //陣列
	size_t _size;
	size_t _capacity;//有多少個有效資料
}SeqList;

void CheckCapacity(SeqList*psl);
void SeqListInit(SeqList* psl,size_t capacity);//初始化
void SeqListDestory(SeqList* psl);//銷燬

void SeqListPushBack(SeqList* psl, SLDateType x);//尾插
void SeqListPopBack(SeqList* psl);//頭插
void SeqListPushFront(SeqList* psl, SLDateType x);//尾刪
void SeqListPopFront(SeqList* psl);//頭刪

int SeqListFind(SeqList*psl,SLDateType x);
void SeqListInsert(SeqList* psl, size_t pos, SLDateType x);//中間插入
void SeqListErase(SeqList* psl, size_t pos);//給下標,刪除下標處的東西
void SeqListRemove(SeqList* psl,SLDateType x);//給一個x,刪除它
void SeqListPrint(SeqList* psl);
void SeqListModify(SeqList*psl, size_t pos, SLDateType x);
void TestSeqList();

void SeqListBubbleSort(SeqList*psl);
void SeqListBinaryFind(SeqList*psl, SLDateType x);
void SeqListRemoveAll(SeqList*psl, SLDateType x);

#endif //_SEQLIST_H_

Seqlist.c

#include "SeqList.h"

void SeqListInit(SeqList* psl, size_t capacity)//初始化
{
	assert(psl);
	if (capacity == 0)
	{
		psl->_a = NULL;
		psl->_capacity = 0;
		psl->_size = 0;
	}
	else
	{
		psl->_a = (SLDateType*)malloc(sizeof((SLDateType*)capacity));
		psl->_capacity = capacity;
		psl->_size = 0;
		assert(psl->_a);
	}
}
void SeqListDestory(SeqList*psl)//銷燬
{
	assert(psl);

	free(psl->_a);
	psl->_a = NULL;
	psl->_size = psl->_capacity = 0;
}
void CheckCapacity(SeqList*psl)
{
	if (psl->_size == psl->_capacity)
	{
		SLDateType* tmp;
		if (psl->_capacity == 0)
		{
			psl->_capacity = 2;
		}
		tmp = realloc(psl->_a, psl->_capacity * 2 * sizeof(SLDateType));
		assert(tmp);
		psl->_a = tmp;
		psl->_capacity *= 2;
	}
}
void SeqListPushBack(SeqList*psl, SLDateType x)//尾插
{
	assert(psl);
	CheckCapacity(psl);
	psl->_a[psl->_size] = x;
	psl->_size++;
}
void SeqListPopBack(SeqList*psl)//尾刪
{
	assert(psl);
	if (psl->_size>0)
	{
		psl->_size--;
	}

}
void SeqListPushFront(SeqList*psl, SLDateType x)//頭插
{
	int end=0;
	assert(psl);
	CheckCapacity(psl);
	end = psl->_size;
	while (end >= 0)
	{
		psl->_a[end + 1] = psl->_a[end];
		--end;
	}
	psl->_a[0] = x;
	psl->_size++;
}
void SeqListPopFront(SeqList*psl)//頭刪
{
	assert(psl);
	if (psl->_size > 0)
	{
		int start = 0;
		while (start < (int)psl->_size-1)
		{
			psl->_a[start] = psl->_a[start + 1];
			start++;
		}
		psl->_size--;
	}
	
}
void SeqListInsert(SeqList*psl, size_t pos, SLDateType x)//中間插入
{
	int end = 0;
	end=psl->_size - 1;
	assert(psl&&pos<=psl->_size);
	CheckCapacity(psl);
	while (end >= (int)pos)
	{
		psl->_a[end + 1] = psl->_a[end];
		--end;
	}
	psl->_a[pos] = x;
	psl->_size++;
}
void SeqListErase(SeqList*psl, size_t pos)//給下標,刪除下標處的東西
{
	assert(psl&&pos<psl->_size);
	int start = 0;
	start = pos;
	while (start < (int)psl->_size - 1)
	{
		psl->_a[start] = psl->_a[start + 1];
		++start;
	}
	--psl->_size;
}
int SeqListFind(SeqList*psl,SLDateType x)
{
	int i = 0;
	assert(psl);
	for (i = 0; i < (int)psl->_size; ++i)
	{
		if (psl->_a[i] == x)
		{
			return i;
		}
	}
	return -1;

}
void SeqListRemove(SeqList*psl,SLDateType x)//給一個x,刪除它
{
	int pos = 0;
	assert(psl);
	pos = SeqListFind(psl, x);
	if (pos != -1)
	{
		SeqListErase(psl, pos);
	}
}
void SeqListPrint(SeqList* psl)
{
	size_t i = 0;
	assert(psl);
	for (i = 0; i < psl->_size; ++i)
	{
		printf("%d", psl->_a[i]);
	}
	printf("\n");
}
void SeqListModify(SeqList*psl, size_t pos, SLDateType x)
{
	assert(psl&&pos < psl->_size);
	psl->_a[pos] = x;
}

void SeqListBubbleSort(SeqList*psl);
void SeqListBinaryFind(SeqList*psl, SLDateType x);
void SeqListRemoveAll(SeqList*psl, SLDateType x);

void TestSeqList()
{
	SeqList sl;
	SeqListInit(&sl, 10);
	SeqListPushBack(&sl, 2);
	SeqListPushBack(&sl, 3);
	SeqListPushBack(&sl, 4);
	SeqListPushBack(&sl, 5);
	SeqListPushFront(&sl, 0);
	SeqListInsert(&sl, 2, 6);
	SeqListPrint(&sl);

	//SeqListPopBack(&sl);
	//SeqListPopBack(&sl);
	//SeqListPopBack(&sl);
    //SeqListPopBack(&sl);
	//SeqListPopFront(&sl);
	SeqListRemove(&sl, 3);
	SeqListPrint(&sl);

	SeqListDestory(&sl);
}


main.c 

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
int main()
{
	TestSeqList();
	system("pause");
	return 0;
}