順序表總結以及代碼實現

1.順序表概念

順序表是用一段物理地址連續的存儲單元依次存儲數據元素的線性結構,一般情況下采用數組存儲。在數組上完成數據的增刪查改。
順序表一般可以分爲:

  1. 靜態順序表:使用定長數組存儲。
  2. 動態順序表:使用動態開闢的數組存儲。

2.接口實現:

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

3.代碼實現:

<test.h>

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

// 順序表的動態存儲
typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* array; // 指向動態開闢的數組 
	size_t size; // 有效數據個數 
	size_t capicity; // 容量空間的大小 
}SeqList;

// 基本增刪查改接口 
void SeqListInit(SeqList* psl, size_t capacity);
void SeqListDestory(SeqList* psl);

void CheckCapacity(SeqList* psl);
void SeqListPushBack(SeqList* psl, SLDataType x);
void SeqListPopBack(SeqList* psl);
void SeqListPushFront(SeqList* psl, SLDataType x);
void SeqListPopFront(SeqList* psl);

int SeqListFind(SeqList* psl, SLDataType x);
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x);
void SeqListErase(SeqList* psl, size_t pos);
void SeqListRemove(SeqList* psl, SLDataType x);
void SeqListModify(SeqList* psl, size_t pos, SLDataType x);
void SeqListPrint(SeqList* psl);

// 擴展面試題實現 
void SeqListBubbleSort(SeqList* psl);
int SeqListBinaryFind(SeqList* psl, SLDataType x);
// 本題要求:時間複雜度:O(N) 空間複雜度 O(1) 
void SeqListRemoveAll(SeqList* psl, SLDataType x);

<test.c>

#include "test.h"

//初始化
void SeqListInit(SeqList* psl, size_t capacity)
{
	assert(psl);
	if (capacity == 0)
	{
		psl->array = NULL;
		psl->size = 0;
		psl->capicity = 0;
	}
	else
	{
			psl->array = (SLDataType*)malloc(sizeof(SLDataType)*capacity);
			psl->size = 0;
			psl->capicity = capacity;
			assert(psl->array);
	}
}
//銷燬
void SeqListDestory(SeqList* psl)
{
	assert(psl);
	free(psl->array);
	psl->array = NULL;
	psl->capicity = 0;
	psl->size = 0;
}
//容量檢測
void CheckCapacity(SeqList* psl)
{
	if (psl->size == psl->capicity)
	{
		SLDataType* tmp;
		if (psl->capicity == 0)
		{
			psl->capicity = 2;
		}
		else
		{
			tmp = realloc(psl->array, psl->capicity * 2 * sizeof(SLDataType));
			assert(tmp);
			psl->array = tmp;
			psl->capicity *= 2;
		}
	}
}
//尾插
void SeqListPushBack(SeqList* psl, SLDataType x)
{
	assert(psl);
	CheckCapacity(psl);
	psl->array[psl->size] = x;
	psl->size++;
}
//尾刪
void SeqListPopBack(SeqList* psl)
{
	assert(psl);
	if (psl->size > 0)
	{
		psl->size--;
	}
}
//頭插
void SeqListPushFront(SeqList* psl, SLDataType x)
{
	assert(psl);
	int end;
	CheckCapacity(psl);
	end = psl->size;
	while (end >= 1)
	{
		psl->array[end] = psl->array[end - 1];//注意條件,避免越界訪問
		end--;
	}
	psl->array[0] = x;
	psl->size++;
}
//頭刪
void SeqListPopFront(SeqList* psl)
{
	assert(psl);
	if (psl->size > 0)
	{
		size_t start;
		start = psl->array[0];
		while (start < psl->size - 1)
		{
			psl->array[start] = psl->array[start + 1];
			start++;
		}
		psl->size--;
	}
}
//查找
int SeqListFind(SeqList* psl, SLDataType x)
{
	assert(psl);
	size_t i = 0;
	for (i = 0; i < psl->size; i++)
	{
		if (psl->array[i] == x)
		{
			return i;
		}
	}
	return -1;
}
//任何pos位置的插入數據
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x)
{
	int end;
	assert(psl);
	CheckCapacity(psl);
	end = psl->size - 1;
	while ((int)pos <= end)
	{
		psl->array[end + 1] = psl->array[end];
		end--;
	}
	psl->array[pos] = x;
	psl->size++;
}
//刪除pos位置的數據
void SeqListErase(SeqList* psl, size_t pos)
{
	assert(psl);
	size_t start = pos;
	while (start<psl->size - 1)
	{
		psl->array[start] = psl->array[start + 1];
		start++;
	}
	psl->size--;
}
//刪除指定數據
void SeqListRemove(SeqList* psl, SLDataType x)
{
	assert(psl);
	size_t  pos;
	pos = SeqListFind(psl, x);
	if (pos != -1)
	{
		SeqListErase(psl, pos);
	}
}
//修改某個位置(下標)的數據
void SeqListModify(SeqList* psl, size_t pos, SLDataType x)
{
	assert(psl);
	psl->array[pos] = x;
}
//輸出順序表
void SeqListPrint(SeqList* psl)
{
	size_t i = 0;
	assert(psl);
	for (i = 0; i < psl->size; i++)
	{
		printf("%3d ", psl->array[i]);
	}
	printf("\n");
}
void SeqListBubbleSort(SeqList* psl)//冒泡排序
{
	assert(psl);
	size_t i = 0;
	size_t j = 0;
	for (i = 0; i < psl->size - 1; i++)
	{
		int flag = 0;
		for (j = 0; j < psl->size - 1 - i; j++)
		{
			if (psl->array[j]>psl->array[j + 1])
			{
				SLDataType tmp = psl->array[j + 1];
				psl->array[j + 1] = psl->array[j];
				psl->array[j] = tmp;
				flag = 1;
			}
		}
		if (0 == flag)
		{
			return;
		}
	}
}

int BinarySearch(SeqList* psl, SLDataType x)//二分查找
{
	assert(psl);
	int left = 0;
	int right = psl->size - 1;
	while (left <= right)
	{
		SLDataType mid = left + (right - left);
		if (psl->array[mid] < x)
		{
			left = mid + 1;
		}
		else if (psl->array[mid] > x)
		{
			right = mid - 1;
		}
		else
		{
			return mid;
		}
	}
	return 0;
}

void SeqListRemoveAll(SeqList* psl, SLDataType x)//要求時間複雜度是O(N) 空間複雜度O(1)
{
	assert(psl);
	SLDataType ret = 0;
	size_t i = 0;
	while (i < psl->size - 1)
	{
		ret = SeqListFind(psl, x);
		if (ret != -1)
		{
			SeqListRemove(psl, x);
		}
		i++;
	}
}







void TestSeqList()
{
	SeqList sl;
	SeqListInit(&sl, 10);

	SeqListPushBack(&sl, 1);
	SeqListPushBack(&sl, 9);
	SeqListPushBack(&sl, 2);
	SeqListPushBack(&sl, 6);
	SeqListPushBack(&sl, 3);
	SeqListPushBack(&sl, 7);
	SeqListPushBack(&sl, 4);
	SeqListPushBack(&sl, 8);
	SeqListPushBack(&sl, 5);
	SeqListPrint(&sl);

	SeqListPopBack(&sl);
	SeqListPrint(&sl);

	SeqListPushFront(&sl, 0);
	SeqListPrint(&sl);

	SeqListPopFront(&sl);
	SeqListPrint(&sl);

	SeqListFind(&sl, 4);
	SeqListInsert(&sl, 2, 6);
	SeqListPrint(&sl);

	SeqListErase(&sl, 3);
	SeqListPrint(&sl);

	SeqListModify(&sl, 1, 7);
	SeqListPrint(&sl);

	SeqListRemove(&sl, 7);
	SeqListPrint(&sl);

	SeqListBubbleSort(&sl);
	SeqListPrint(&sl);

	printf("%d\n", BinarySearch(&sl, 2));

	SeqListRemoveAll(&sl, 6);
	SeqListPrint(&sl);

}



int main()
{
	TestSeqList();
	system("pause");
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章