1. 程式人生 > >【資料結構】靜態順序表各種功能實現(C語言)

【資料結構】靜態順序表各種功能實現(C語言)

順序表的儲存方式

在這裡插入圖片描述

定義一個順序表

#define MAX_SIZE (100)
 typedef int DataType; 
 typedef struct SeqList 
 { 
 	DataType data[MAX_SIZE]; 
 	int size; 
 }	SeqListR;

順序表要實現的功能

 void InitSeqList(SeqListR *pSeq);
 //初始化順序表

 void DestroySeqList(SeqListR *pSeq);
 //銷燬順序表

 void PrintSeqList(const SeqListR *pSeq);
 //列印順序表的內容

 void
PushBack(SeqListR *pSeq, DataType data); //在順序表的尾部插入一個值為data的元素 void PushFront(SeqListR *pSeq, DataType data); //在順序表的頭部插入一個值為data的元素 void Insert(SeqListR *pSeq, int pos, DataType d); //在順序表的pos位置處插入一個值為data的元素 void PopBack(SeqListR *pSeq); //在順序表的尾部刪除一個元素 void PopFront(SeqListR *pSeq); //在順序表的頭部刪除一個元素
void Erase(SeqListR *pSeq,int pos); //在pos位置處刪除一個元素 void Sort(SeqListR *pSeq); //氣泡排序 void SelectSearch(SeqListR *pSeq); //選擇排序 int BinarySearch(SeqListR *pSeq, DataType data); //二分查詢 int Find( const SeqListR *pSeq, DataType data); //在一個無序順序表中查詢一個data的元素,找到返回所在的位置,找不到返回-1 void Remove(SeqListR *
pSeq, DataType data); //刪除順序表中第一次遇到data void RemoveAll(SeqListR *pSeq,DataType data); //刪除順序表中所有的data

各項功能的具體實現

#include "Seqlist.h"
#include <assert.h>

void InitSeqList(SeqListR *pSeq) //初始化順序表
{
	assert(pSeq != NULL);
	int i = 0;
	pSeq->size = 0;
}


void DestroySeqList(SeqListR *pSeq)//銷燬順序表
{
	assert(pSeq != NULL);
	pSeq->size = 0;
}


void PrintSeqList(const SeqListR *pSeq)//列印順序表
{
	for (int i = 0; i < pSeq->size; i++)
	{
		printf(" %d ", pSeq->data[i]);
	}
	printf("\n");
}


void PushBack(SeqListR *pSeq, DataType data)//尾插
{
	if (pSeq->size == MAX_SIZE)
	{
		printf("滿了\n");
		return;
	}
	pSeq->data[pSeq->size] = data;//在size所指的位置插入數字
	pSeq->size += 1;
}


void PushFront(SeqListR *pSeq, DataType data)//頭插
{
	if (pSeq->size == MAX_SIZE)
	{
		printf("滿了\n");
		return;
	}
	for (int i = pSeq->size - 1; i >= 0; i--)//i的含義是資料的下標
	{
		pSeq->data[i+1] = pSeq->data[i];
	}
	for (int j = pSeq->size; j > 0; j--)//j的含義是空間的下標
	{
		pSeq->data[j] = pSeq->data[j-1];
	}
	pSeq->data[0] = data;
	pSeq->size++;
}


void Insert(SeqListR *pSeq, int pos, DataType data)//指定位置的插入
{
	assert(pSeq->size < MAX_SIZE);
	assert(pos >= 0 && pos <= pSeq->size);
	for (int i = pSeq->size ; i >= pos + 1; i--)//i的含義是資料的下標
	{
		pSeq->data[i] = pSeq->data[i-1];
	}
	pSeq->data[pos] = data;
	pSeq->size+=1;
}


void PopBack(SeqListR *pSeq)//尾刪
{
	assert(pSeq != NULL);//傳入地址不為空
	assert(pSeq->size > 0);//順序表不為空
	pSeq->size--;
}


void PopFront(SeqListR *pSeq)//頭刪
{
	assert(pSeq != NULL);
	assert(pSeq->size > 0);
	for (int i = 1; i <= pSeq->size-1; i++)//i的含義是資料的下標
	{
		pSeq->data[ i ] = pSeq->data[i+1];
	}
	//for (int j = 0; j <= pSeq->size - 2; j++)//j的含義是空間的下標
	//{
	//	pSeq->data[j] = pSeq->data[j + 1];
	//}
	//pSeq->size--;

}


void Erase(SeqListR *pSeq, int pos)//指定位置的刪除
{
	assert(pSeq != NULL);//傳入地址不為空
	assert(pSeq->size > 0);//順序表不為空
	assert(pos >= 0 && pos < pSeq->size);//刪除的數的位置不能超過size的大小
	for (int i = pos; i <= pSeq->size - 2; i++)
	{
		pSeq->data[i] = pSeq->data[i + 1];
	}
	pSeq->size--;
}

int Find(SeqListR *pSeq, DataType data)//查詢無序順序表
{
	for (int i = 0; i < pSeq ->size; i++)
	{
		if (data == pSeq->data[i])
		{
			return i;
		}
	}
	return -1;
}

void Remove(SeqListR *pSeq, DataType data)//刪除第一個遇到的數字
{
	int pos = Find(pSeq, data);
	if (pos == -1);
	{
		return -1;
	}
	Erase(pSeq, pos);
	//for (int i = 0; i <= pSeq->size; i++)
	//{
	//	if (data == pSeq->data[i])
	//	{
	//		for (int j = i; j <= pSeq->size - 2; j++)
	//		{
	//			pSeq->data[j] = pSeq->data[j + 1];
	//		}
	//		pSeq->size--;
	//	}
	//}
}


void RemoveAll(SeqListR *pSeq, DataType data)//刪除查詢到的所有data
{
	while (Remove(pSeq, data) != -1)
	{
	}
	//時間複雜度O(n^2)
	
	int i = 0;
	int j = 0;
	//新建陣列,把不等於 data 的資料 copy 到 extra
	DataType *extra = (DataType *)malloc(sizeof(DataType)*pSeq->size);
	for (; i < pSeq->size; i++)
	{
		if (pSeq->data[i] != data)
		{
			extra[j++] = pSeq->data[i];
		}
	}
	//從extra拷貝回原來的順序表
	for (int k = 0; k < j; k++)
	{
		pSeq->data[k] = extra[k];
	}
	pSeq->size = j;//j剛好就是剩下的資料個數
	free(extra);
	//空間複雜度O(n)

	int i = 0, j = 0;
	for (; i < pSeq->size; i++)
	{
		if (pSeq->data[i] != data)
		{
			pSeq->data[j++] = pSeq->data[i];
		}
	}
	pSeq->size = j;
	//空間複雜度O(1)
}

void Swap(DataType *a, DataType *b)
{
	DataType t = *a;
	*a = *b;
	*b = t;
}


void Sort(SeqListR *pSeq)//氣泡排序
{
	int i = 0, j = 0;
	bool sorted = true;
	for (i = 0; i < pSeq->size; i++)
	{
		sorted = true;
		for (j = 0; j < pSeq->size - i; j++)
		{
			if (pSeq->data[j] > pSeq->data[j + 1])
			{
				Swap(pSeq->data[j], pSeq->data[j + 1]);
				sorted = false;
			}
		}
		 //一次冒泡過程中,一次交換都沒有,所以已經有序了
		if (sorted)
		{
			break;
		}
	}
}


int BinarySearch(SeqListR *pSeq, DataType data)//二分查詢
{
	int left = 0;
	int right = pSeq->size;
	while (left < right)
	{
		int mid = left + ( right - left ) / 2;
		if (pSeq->data[mid] == data)
		{
			return mid;
		}
		else if (pSeq->data[mid] > data)
		{
			right = mid;
		}
		else if (pSeq->data[mid] < data)
		{
			left = mid;
		}
		else
		{
			return -1;
		}
	}	
}


void SelectSearch(SeqListR *pSeq)//選擇排序
{
	int minSpace = 0;
	int maxSpace = pSeq->size-1;
	while (minSpace<maxSpace)//區間內只剩一個數或零個數
	{
		int minPos = minSpace;//假設第一個就是最小的
		int maxPos = minSpace;//假設第一個就是最大的
		for (int j = minSpace; j <= maxSpace; j++)
		{ 
			if (pSeq->data[j] < pSeq->data[minPos])
			{
				minPos = j;//找到最小的數存在的位置
			}
			if (pSeq->data[j] > pSeq->data[maxPos])
			{
				maxPos = j;//找到最大的數存在的位置
			}
		}

		Swap(pSeq->data + minSpace, pSeq->data + minPos);//找到最小的數放在最小的位置
		 // 最大的數就是區間內的第一個的時候
		if (minSpace == maxPos) 
		{
			maxPos = minPos;
		}
		Swap(pSeq->data + maxSpace, pSeq->data + maxPos);

		minSpace++;
		maxSpace--;
		}
}