順序表,全名順序存儲結構,是線性表的一種
順序表存儲數據時,會提前申請一整塊足夠大小的物理空間,然後將數據依次存儲起來,存儲時做到數據元素之間不留一絲縫隙。
使用順序表存儲數據之前,除了要申請足夠大小的物理空間之外,爲了方便後期使用表中的數據,順序表還需要實時記錄以下 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 種情況:
- 插入到順序表的表頭;
- 在表的中間位置插入元素;
- 尾隨順序表中已有元素,作爲順序表中的最後一個元素;
通過遍歷,找到數據元素要插入的位置,然後做如下兩步工作:
- 將要插入位置元素以及後續的元素整體向後移動一個位置;
- 將元素放到騰出來的位置上;
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;//查找失敗
}
順序表更改元素
順序表更改元素的實現過程是:
- 找到目標元素;
- 直接修改該元素的值;
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;
}