數據結構--順序表總結

順序表,全名順序存儲結構,是線性表的一種

順序表存儲數據時,會提前申請一整塊足夠大小的物理空間,然後將數據依次存儲起來,存儲時做到數據元素之間不留一絲縫隙。

使用順序表存儲數據之前,除了要申請足夠大小的物理空間之外,爲了方便後期使用表中的數據,順序表還需要實時記錄以下 2 項數據:

  1. 順序表申請的存儲容量;
  2. 順序表的長度,也就是表中存儲數據元素的個數;

自定義一個順序表

typedef struct Table{
    int * head;//聲明瞭一個名爲head的長度不確定的數組,也叫“動態數組”
    int length;//記錄當前順序表的長度
    int size;//記錄順序表分配的存儲容量
}table;

 

建立順序表需要做如下工作:給 head 動態數據申請足夠大小的物理空間;給 size 和 length 賦初值;

#define Size 5 //對Size進行宏定義,表示順序表申請空間的大小
table initTable(){
    table t;
    t.head=(int*)malloc(Size*sizeof(int));//構造一個空的順序表,動態申請存儲空間
    if (!t.head) //如果申請失敗,作出提示並直接退出程序
    {
        printf("初始化失敗");
        exit(0);
    }
    t.length=0;//空表的長度初始化爲0
    t.size=Size;//空表的初始存儲空間爲Size
    return t;
}
#include <stdio.h>
#include <stdlib.h>

#define Size  6

typedef struct Table
{
	int * head;
	int len;
	int size;
}table;

table initTable()
{
	table t;
	t.head = (int*)malloc(Size*sizeof(int));
	if (!t.head)
	{
		printf("初始化失敗!");
		exit(0);
	}
	t.len = 0;
	t.size = Size;
	return t;
}

void Print(table t)
{
	for (int i = 0; i < t.len; ++i)
	{
		printf("%d ",t.head[i]);
	}
	printf("\n");
}
int main()
{
	table t = initTable();
	for (int i =1; i < Size; ++i)
	{
		t.head[i-1] = i;
		t.len++;
	}
	Print(t);
	system("pause");
	return 0;
}

順序表插入元素

向已有順序表中插入數據元素,根據插入位置的不同,可分爲以下 3 種情況:

  1. 插入到順序表的表頭;
  2. 在表的中間位置插入元素;
  3. 尾隨順序表中已有元素,作爲順序表中的最後一個元素;

通過遍歷,找到數據元素要插入的位置,然後做如下兩步工作:

  • 將要插入位置元素以及後續的元素整體向後移動一個位置;
  • 將元素放到騰出來的位置上;
table AddTable(table t, int num, int add)
{
	//判斷插入本身是否存在問題(如果插入元素位置比整張表的長度+1還大
	//(如果相等,是尾隨的情況)
	//或者插入的位置本身不存在,程序作爲提示並自動退出)
	if (add > t.len + 1 || add < 1)
	{
		printf("插入位置有誤");
		return t;
	}
	if (t.len == t.size)
	{
		//做插入操作時,首先需要看順序表是否有多餘的存儲空間提供給插入的元素,
		//如果沒有,需要申請
		//動態數組額外申請更多物理空間使用的是 realloc 函數。
	    //並且,在實現後續元素整體後移的過程,
		//目標位置其實是有數據的,只是下一步新插入元素時會把舊元素直接覆蓋。
		t.head = (int*)realloc(t.head, (t.size + 1)*sizeof(int));
		if (!t.head)
		{
			printf("申請失敗");
			return t;
		}
		t.size += 1;
	}
	//插入操作,需要將從插入位置開始的後序元素,逐個後移
	for (int i = t.len - 1; i >= add - 1; --i)
	{
		t.head[i + 1] = t.head[i];
	}
	t.head[add - 1] = num;
	t.len++;
	return t;
}

int main
{
    .....
   //第五個位置插入1
	AddTable(t, 1, 5);
}

順序表刪除元素

從順序表中刪除指定元素,實現起來非常簡單,只需找到目標元素,並將其後續所有元素整體前移 1 個位置即可。

後續元素整體前移一個位置,會直接將目標元素刪除,可間接實現刪除元素的目的

//刪除元素
table delTable(table t,int add)
{
	if (add > t.len || add < 1)
	{
		printf("刪除位置有誤");
		return t;
	}
	for (int i = add; i < t.len; ++i)
	{
		t.head[i - 1] = t.head[i];
	}
	t.len--;
	return t;
}
int main{
......
//刪除第四個位置元素
	delTable(t,4);
}

順序表查找元素

順序表中查找目標元素,可以使用多種查找算法實現,比如說二分查找算法、插值查找算法等。 這裏,我們選擇順序查找算法

//查找元素

int  findTable(table t, int num)
{
	for (int i = 0; i < t.len; ++i)
	{
		if (t.head[i] == num)
		{
			return i + 1;
		}
	}
	return -1;//查找失敗
}

順序表更改元素

順序表更改元素的實現過程是:

  1. 找到目標元素;
  2. 直接修改該元素的值;
table ChangeTable(table t, int num, int newnum)
{
	int add = findTable(t, num);
	t.head[add - 1] = newnum;
	return t;
}

所有集合代碼

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

#define Size  10

typedef struct Table
{
	int * head;
	int len;
	int size;
}table;
//num爲插入的數字,add爲插入的位置
table AddTable(table t, int num, int add)
{
	//判斷插入本身是否存在問題(如果插入元素位置比整張表的長度+1還大
	//(如果相等,是尾隨的情況)
	//或者插入的位置本身不存在,程序作爲提示並自動退出)
	if (add > t.len + 1 || add < 1)
	{
		printf("插入位置有誤");
		return t;
	}
	if (t.len == t.size)
	{
		//做插入操作時,首先需要看順序表是否有多餘的存儲空間提供給插入的元素,
		//如果沒有,需要申請
		//動態數組額外申請更多物理空間使用的是 realloc 函數。
	    //並且,在實現後續元素整體後移的過程,
		//目標位置其實是有數據的,只是下一步新插入元素時會把舊元素直接覆蓋。
		t.head = (int*)realloc(t.head, (t.size + 1)*sizeof(int));
		if (!t.head)
		{
			printf("申請失敗");
			return t;
		}
		t.size += 1;
	}
	//插入操作,需要將從插入位置開始的後序元素,逐個後移
	for (int i = t.len - 1; i >= add - 1; --i)
	{
		t.head[i + 1] = t.head[i];
	}
	t.head[add - 1] = num;
	t.len++;
	return t;
}

//刪除元素
table delTable(table t,int add)
{
	if (add > t.len || add < 1)
	{
		printf("刪除位置有誤");
		return t;
	}
	for (int i = add; i < t.len; ++i)
	{
		t.head[i - 1] = t.head[i];
	}
	t.len--;
	return t;
}

//初始化順序表
table initTable()
{
	table t;
	t.head = (int*)malloc(Size*sizeof(int));
	if (!t.head)
	{
		printf("初始化失敗!");
		exit(0);
	}
	t.len = 0;
	t.size = Size;
	return t;
}
//打印輸出
void Print(table t)
{
	for (int i = 0; i < t.len; ++i)
	{
		printf("%d ",t.head[i]);
	}
	printf("\n");
}

//查找元素

int  findTable(table t, int num)
{
	for (int i = 0; i < t.len; ++i)
	{
		if (t.head[i] == num)
		{
			return i + 1;
		}
	}
	return -1;//查找失敗
}

//更改元素
table ChangeTable(table t, int num, int newnum)
{
	int add = findTable(t, num);
	t.head[add - 1] = newnum;
	return t;
}

int main()
{
	table t = initTable();
	
	for (int i =1; i <= Size; ++i)
	{
		t.head[i-1] = i;
		t.len++;
	}
	Print(t);
	//第五個位置插入1
	AddTable(t, 1, 5);
	Print(t);
	//刪除第四個位置元素
	delTable(t,4);
	Print(t);

	int add = findTable(t, 6);
	printf("%d\n",add);
	//將元素2改爲4
	t = ChangeTable(t, 2, 4);
	Print(t);
	system("pause");
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章