1. 程式人生 > >C語言實現靜態順序表

C語言實現靜態順序表

實現順序表分為以下幾步

1.先寫出封裝順序表結構的結構體;

2.初始化順序表;

3.增刪查改;

4.順序表的逆置等。

#define MAX_SIZE 100
typedef int DataType;

typedef struct SeqList
{
	DataType data[MAX_SIZE];
	DataType length;
}SeqList;
//順序表的初始化就是把順序表初始化成空的順序表,再把順序表長度置0即可
void InitSeqList(SeqList *pList)
{
	if(pList == NULL)
	{
		return ;
	}
	pList->length = 0;
}
//獲取順序表的長度,順序表元素個數即位順序表長度
int GetLengthSeqList(SeqList *pList)
{
	assert(pList);
	return pList->length;
}
//查詢順序表中第i個元素,按順序查詢,判斷是否合法即可
int FindiSeqList(SeqList *pList, int i)
{
	assert(pList);
	if(pList->length < 1 || pList->length > GetLengthSeqList(pList))
	{
		return 0;
	}
	//因為陣列下標是從0開始的,而陣列元素是從1開始的。
	return pList->data[i-1];
}
//插入操作:在指定位置i插入一個元素,首先考慮順序表是不是已經滿了,插入位置合不合法,
//其次,插入後,i之後所有元素都必須向後移動移位,必須得從最後一位開始移動,然後將i-1這個陣列下標的元素改為d,最後再將順序表長度+1。
int InsertSeqList(SeqList *pList, int i, DataType d)
{
	int k = 0;
	assert(pList);
	if(pList->length < 1 || pList->length > GetLengthSeqList(pList))
	{
		return 0;
	}
	else if(pList->length >= MAX_SIZE)
	{
		return 0;
	}
	else
	{
		//pList->length這裡求出來的是元素的個數,元素個數比陣列下標大1,正好就i之後所有元素向後移了一位
		//這裡k=i-1很重要,因為順序表是從0開始的,如果不-1,我們就找不到i在順序表中正確的位置,以至於i在順序表中原本的那個值就無法給後面的元素
		for(k = pList->length; k >= i-1; k--)
		{
			pList->data[k+1] = pList->data[k];
		}
		pList->data[i-1] = d;
		pList->length++;
		return 1;
	}
}
//刪除操作:在指定位置i刪除一個元素d,需要將表中第i個元素之後的所有元素向前移位移位,再將順序表長度-1.
void DeleteSeqList(SeqList *pList, int i)
{
	assert(pList);
	if(pList->length < 1 || pList->length > GetLengthSeqList(pList))
	{
		return ;
	}
	else
	{
		while(i < pList->length)
		{
			pList->data[i-1] = pList->data[i];
			i++;
		}
		pList->length--;
	}
}
//按內容查詢:先找到這個元素,然後返回這個元素的下標+1即可
int GetLocateSeqList(SeqList *pList, DataType d)
{
	int i = 0;
	assert(pList);
	for(i = 0; i <= pList->length; i++)
	{
		if(pList->data[i] == d)
		{
			return i+1;
		}
	}
	return 0;
}
//判斷順序表是否為滿順序表
int IsFullSeqList(SeqList *pList)
{
	assert(pList);
	return (pList->length == MAX_SIZE);
}
//判斷順序表是否為空:如果順序表的長度為0,則順序表為空
int IsEmptySeqList(SeqList *pList)
{
	assert(pList);
	if(pList->length == 0)
	{
		return 1;
	}
	return 0;
}
//尾插:先檢測順序表是否已滿,滿了就返回,未滿就可以插入,在順序表最後一個元素在接上一個元素,結束後給順序表長度+1.
void PushBackSeqList(SeqList *pList, DataType d)
{
	assert(pList);
	if(IsFullSeqList(pList))
	{
		return ;
	}
	else
	{
		pList->data[pList->length] = d;
		pList->length++;
	}
}
//尾刪:先判斷順序表是不是為空,刪掉最後一個元素,然後順序表長度-1.
void PopBackSeqList(SeqList *pList)
{
	assert(pList);
	if(IsEmptySeqList(pList))
	{
		return ;
	}
	else
	{
		pList->length--;
	}
}
//頭插:先判斷順序表是否為滿順序表,如果滿就返回,不滿就插入,相當於從第i個位置插入一個元素,只不過這個i位置為1.
void PushFrontSeqList(SeqList *pList, DataType d)
{
	int i = 0;
	assert(pList);
	if(IsFullSeqList(pList))
	{
		return ;
	}
	else
	{
		for(i = pList->length; i >= 0; i--)
		{
			pList->data[i+1] = pList->data[i];
		}
		pList->data[0] = d;
		pList->length++;
	}
}
//頭刪:先判斷順序表是否為空,如果不為空,從1位置處開始給前一位賦值。
void PopFrontSeqList(SeqList *pList)
{
	int i = 0;
	assert(pList);
	if(IsEmptySeqList(pList))
	{
		return ;
	}
	else
	{
		for(i = 0; i < pList->length; i++)
		{
			pList->data[i] = pList->data[i+1];
		}
		pList->length--;
	}
}
//求順序表的大小
int SizeOfSeqList(SeqList *pList)
{
	assert(pList);
	return (pList->length);
}
//清空順序表,因為不存在記憶體開闢,也不需要記憶體釋放,只需將順序表的長度置為0即可。
void ClearSeqList(SeqList *pList)
{
	assert(pList);
	pList->length = 0;
}
void PrintSeqList(SeqList *pList)
{
	int i;
	for(i = 0; i < pList->length; i++)
	{
		printf("%3d", pList->data[i]);
	}
	printf("\n");
}
//氣泡排序
void BubbleSortSeqList(SeqList *pList)
{
	int i = 0;
	int j = 0;
	assert(pList);
	//for(i = 0; i < pList->length-1; i++)
	//{
	//	for(j = 0; j < pList->length - i - 1; j++)
	//	{
	//		if(pList->data[j] < pList->data[j+1])
	//		{
	//			int tmp = pList->data[j];
	//			pList->data[j] = pList->data[j+1];
	//			pList->data[j+1] = tmp;
	//		}
	//	}
	//}
	for(i = 0; i < pList->length-1; i++)
	{
		for(j = pList->length-2; j >= i; j--)
		{
			if(pList->data[j] < pList->data[j+1])
			{
				int tmp = pList->data[j];
				pList->data[j] = pList->data[j+1];
				pList->data[j+1] = tmp;
			}
		}
	}
}


//選擇排序:
void SelectSortSeqList(SeqList *pList)
{
	int i, j, min;
	assert(pList);
	for(i = 0; i < pList->length-1; i++)
	{
		min = i;
		for(j = i+1; j < pList->length; j++)
		{
			if(pList->data[min] > pList->data[j])
			{
				min = j;
			}
		}
		if(min != i)
		{
			int tmp = pList->data[i];
			pList->data[i] = pList->data[min];
			pList->data[min] = tmp;
		}
	}
}
//選擇排序優化:定義兩個指標,兩邊同時進行選擇,會比之前的版本快一半。
void SelectSortSeqList_OP(SeqList *pList)
{
	int i = 0;
	int tmp;
	int left = 0;
	int right = pList->length-1;
	
	assert(pList);
	while(left < right && (left < pList->length && right >= 0))
	{
		int min = left;
		int max = right;
		for(i = left; i <= right; i++)
		{
			if(pList->data[i] < pList->data[min])
				min = i;
			if(pList->data[i] > pList->data[max])
				max = i;
		}
		tmp = pList->data[max];
		pList->data[max] = pList->data[right];
		pList->data[right] = tmp;
		//特別注意這條判斷:
		//因為這是最極端的情況,最大值和最小值分別在最兩邊,當改變一邊的值之後,比如這個情況,min=5,max=0,但是max之前已經將0位置的值和right的值交換了,
		//而此時如果不判斷min的位置,因為right裡面的值已經改了,在用min去取right裡面的值已經不合理了,只能找被max剛才交換出去的值,才是正確的
		if(min == right)
			min = max;
		tmp = pList->data[min];
		pList->data[min] = pList->data[left];
		pList->data[left] = tmp;
		left++;
		right--;
	}	
}
//二分查詢
int BinarySearchSeqList(SeqList *pList, DataType d)
{
	int left = 0;
	int right = pList->length-1;
	int mid = (pList->length-1)/2;
	assert(pList);
	while(left <= right)
	{
		if(d < pList->data[mid])
		{
			right = mid - 1;
			mid = (left + right)/2;
		}
		else if(d > pList->data[mid])
		{
			left = mid + 1;
			mid = (left + right)/2;
		}
		else
			return mid;
	}
	return -1;
}
//二分查詢遞迴實現
int BinarySearchSeqList_R(SeqList *pList, int left, int right, DataType d)
{
	int mid = (left + right)/2;
	assert(pList);
	while(left <= right)
	{
		if(d < pList->data[mid])
			right = mid - 1;
		else if(d > pList->data[mid])
			left = mid + 1;
		else
			return mid;
		return BinarySearchSeqList_R(pList, left, right, d);
	}
	return -1;
}
//反轉順序表
void ReverseSeqList(SeqList *pList)
{
	int left = 0;
	int right = pList->length-1;
	while(left < pList->length/2)
	{
		int tmp = pList->data[left];
		pList->data[left] = pList->data[right];
		pList->data[right] = tmp;
		left++;
		right--;
	}
}