文章目錄
線性表的順序存儲
線性表的順序存儲是指用一組地址連續的存儲單元依次存儲線性表中的各個元素,使得線性表在邏輯結構上相鄰的元素存儲在連續的物理存儲單元中,即:通過數據元素物理存儲的連續性來反應元素之間邏輯上的相鄰關係。採用順序存儲結構存儲的線性表通常簡稱爲順序表。
順序存儲的線性表的特點:
◆ 線性表的邏輯順序與物理順序一致;
◆ 數據元素之間的關係是以元素在計算機內“物理位置相鄰”來體現。
順序表的線性存儲示意圖
假設線性表中有n個元素,每個元素佔k個存儲單元,第一個元素的地址爲Loc(a1),則第i個元素的地址Loc(ai):
Loc(ai) = Loc(a1) + (i-1) * k;
其中Loc(a1)稱爲基地址。
C語言定義線性表的順序存儲結構
#define ListSize 100 //線性表的最大長度
typedef int DataType;
typedef struct
{
DataType data[ListSize]; //用數組存儲線性表中的元素
DataType length; //順序表中元素的個數
}SeqList, *PSeqList;
DataType是數據元素類型,可以根據需要定義,可以使用SeqList定義數據表類型變量,使用*PSeqList定義數據表指針變量;
順序表的基本操作
(1) 順序表的初始化
順序表的初始化就是把順序表 初始化爲空的順序表;只需把順序表的長度length置爲0即可;
void InitList(PSeqList L)
{
if (L == NULL)
{
return;
}
L->length = 0;
}
(2)求順序表的長度
順序表的長度就是就順序表中的元素的個數,由於在插入和刪除操作中都有對數據表的長度進行修改,所以求表長只需返回length的值即可;
int LengthList(PSeqList L)
{
if (L == NULL)
{
return 0;
}
return L->length;
}
(3)按序號查找
查找順序表中第i個元素的值(按序號查找),如果找到,將將該元素值賦給e。查找第i個元素的值時,首先要判斷查找的序號是否合法,如果合法,返回第i個元素對應的值。
int GetData(PSeqList L, int i)
{
if (L->length < 1 || (L->length > LengthList(L)))
{
return 0;
}
//數據元素的序號從1開始,數組下表從0開始,第i個元素對應的數組下標爲i-1;
return L->data[i - 1];
}
(4)插入操作
在數據表的第i個位置插入元素,在順序表的第i個位置插入元素e,首先將順序表第i個位置的元素依次向後移動一個位置,然後將元素e插入第i個位置,移動元素要從後往前移動元素,即:先移動最後一個元素,在移動倒數第二個元素,依次類推;插入元素之前要判斷插入的位置是否合法,順序表是否已滿,在插入元素之後要將表長L->length++;
int InsList(PSeqList L, int i, DataType e)
{
//判斷插入位置是否合法
if (i < 1 || L->length >(LengthList(L) + 1))
{
printf("插入位置不合法!\n");
return 0;
}
//判斷順序表是否已滿
else if (L->length >= ListSize)
{
printf("順序表已滿,不能插入!\n");
return 0;
}
else
{
for (k = i; k <= L->length; k--)
{
L->data[k + 1] = L->data[k];
}
L->data[i - 1] = e;
L->length++; //數據表的長度加1
return 1;
}
return 0;
}
(5) 刪除操作
刪除表中的第i個元素e,刪除數據表中的第i個元素,需要將表中第i個元素之後的元素依次向前移動一位,將前面的元素覆蓋掉。移動元素時要想將第i+1個元素移動到第i個位置,在將第i+2個元素移動i+1的位置,直到將最後一個元素移動到它的前一個位置,進行刪除操作之前要判斷順序表是否爲空,刪除元素之後,將表長L->length–;
int DelList(PSeqList L, DataType i, DataType* e)
{
if (L->length < 1)
{
printf("表爲空!\n");
return 0;
}
*e = L->data[i - 1];
for (k = i; k < L->length; k++)
{
L->data[k - 1] = L->data[k];
}
L->length--;
return *e;
}
(6)按內容查找
查找數據元素e在表中的位置,可以從表頭開始一直遍歷表中元素,如果找到與要查找元素e相等的元素,則返回元素在表中的位置,數組下標從0開始,則元素在表中對應的位置序號值應爲對應數組下標加1,沒有找到則返回0;
int Locate(PSeqList L, DataType e)
{
for (k = 0; k < L->length; k++)
{
if (L->data[k] == e)
{
//k爲e對應的數組下標,在表中對應序號應爲k+1
return k + 1;
}
}
return 0;
}
(7)頭插
頭插,即在表頭插入元素e,在表頭插入元素,需要將表中的元素依次後移一位,然後將要插入的元素e賦給數字的首元素,執行插入操作後將表長L->length++;需要注意的是移動元素要從順序表的最後一個元素開始移動,如果從第1個元素開始移動,會使得第1個元素的值覆蓋第2個元素的值,然後把第二個元素後移則會使第2個元素的值(原來第1個元素值)覆蓋第3個元素的值,依次類推,最後出插入元素外,其餘元素值均爲原順序表中第一個元素的值。
void PushFront(PSeqList L, DataType e)
{
if (L->length == ListSize)
{
printf("順序表已滿,不能插入!\n");
}
//將表中元素依次後移一位
for (k = L->length; k > 0; k--)
{
L->data[k] = L->data[k - 1];
}
//插入元素
L->data[0] = e;
L->length++;
}
(8)頭刪
刪除順序表中的第一個元素,只要將順序表中的元素從第2個開始,依次向前移動1位,覆蓋原來順序表中元素對應位置的前一個值,在刪除元素之前要判斷順序表是否爲空,刪除順序表元素之後將順序表長度L->length–;
void PopFront(PSeqList L)
{
if (EmptyList(L))
{
printf("順序表爲空\n");
}
for (k = 1; k <= L->length - 1; k++)
{
L->data[k - 1] = L->data[k];
}
L->length--;
}
(9)尾插
在順序表表尾插入元素e,L->data[L->length] = e;將元素e的值賦給順序表中最後一個元素的下一個元素;尾插操作,需要判斷順序表是否已滿,尾插後將順序表長度L->length++;
void PushBack(PSeqList L, DataType e)
{
if (L->length == ListSize)
{
printf("順序表已滿,不能插入!\n");
}
L->data[L->length] = e;
L->length++;
}
(10) 尾刪
刪除表尾元素,只需將順序表的長度減1,類似於出棧操作,棧頂指針top –。
void PopBack(PSeqList L)
{
if (EmptyList(L))
{
printf("表爲空!\n");
}
L->length--;
}
(11) 清空順序表
清空順序表就是將表中的元素刪除。刪除表中的元素只需將表的長度置爲0。
void ClearList(PSeqList L)
{
L->length = 0;
}
(12)判斷表是否爲空
如果順序表的長度爲0,則順序表爲空,返回1,否則,返回0;
int EmptyList(PSeqList L)
{
if (L->length == 0)
{
return 1;
}
return 0;
}
(13)打印表中元素
依次打印順序表中的元素,如果順序表爲空則輸出提示。
void PrintList(PSeqList L)
{
if (EmptyList(L))
{
printf("表爲空!\n");
return;
}
for (k = 0; k < L->length; k++)
{
printf("%-3d", L->data[k]);
}
printf("\n");
}
順序表的基礎操作完整代碼
SeqList.h數據結構的定義和基本操作函數聲明
#pragma once
#define ListSize 100 //線性表的最大長度
typedef int DataType;
typedef struct
{
DataType data[ListSize]; //用數組存儲線性表中的元素
DataType length; //順序表的長度
}SeqList, *PSeqList;
void InitList(PSeqList L); //順序表的初始化操作
int LengthList(PSeqList L); //求順序表的長度
int GetData(PSeqList L, int i); //返回數據表中第i個元素的值
int InsList(PSeqList L, int i, DataType e); //在順序表的第i個位置插入元素
int DelList(PSeqList L, DataType i, DataType* e); //刪除順序表L的第i個數據元素
int Locate(PSeqList L, DataType e); //查找數據元素e在表中的位置
void PushFront(PSeqList L, DataType e); //頭插,在表頭插入元素e
void PopFront(PSeqList L); //頭刪,刪除表中的第一個元素
void PushBack(PSeqList L, DataType e); //尾插,在表尾插入元素e
void PopBack(PSeqList L); //尾刪,刪除表尾元素
void ClearList(PSeqList L); //清空順序表
int EmptyList(PSeqList L); //判斷順序表是否爲空
void PrintList(PSeqList L); //打印表中元素
SeqList.c 函數的具體實現
#include <stdio.h>
#include "SeqList.h"
int k = 0; //全局變量,用於作部分操作的循環變量
//初始化順序表
void InitList(PSeqList L)
{
if (L == NULL)
{
return;
}
L->length = 0;
}
//求順序表的長度
int LengthList(PSeqList L)
{
if (L == NULL)
{
return 0;
}
return L->length;
}
//返回數據表中第i個元素的值
int GetData(PSeqList L, int i)
{
if (L->length < 1 || (L->length > LengthList(L)))
{
return 0;
}
//數據元素的序號從1開始,數組下表從0開始,第i個元素對應的數組下標爲i-1;
return L->data[i - 1];
}
//在L中第i個位置,插入新的數據元素e
int InsList(PSeqList L, int i, DataType e)
{
//判斷插入位置是否合法
if (i < 1 || L->length >(LengthList(L) + 1))
{
printf("插入位置不合法!\n");
return 0;
}
//判斷順序表是否已滿
else if (L->length >= ListSize)
{
printf("順序表已滿,不能插入!\n");
return 0;
}
else
{
for (k = i; k <= L->length; k--)
{
L->data[k + 1] = L->data[k];
}
L->data[i - 1] = e;
L->length++; //數據表的長度加1
return 1;
}
return 0;
}
//刪除L的第i個數據元素
int DelList(PSeqList L, DataType i, DataType* e)
{
if (L->length < 1)
{
printf("表爲空!\n");
return 0;
}
*e = L->data[i - 1];
for (k = i; k < L->length; k++)
{
L->data[k - 1] = L->data[k];
}
L->length--;
return *e;
}
//查找e在表中的位置
int Locate(PSeqList L, DataType e)
{
for (k = 0; k < L->length; k++)
{
if (L->data[k] == e)
{
//k爲e對應的數組下標,在表中對應序號應爲k+1
return k + 1;
}
}
return 0;
}
//頭插,在表頭插入元素e
void PushFront(PSeqList L, DataType e)
{
if (L->length == ListSize)
{
printf("順序表已滿,不能插入!\n");
}
//將表中元素依次後移一位
for (k = L->length; k > 0; k--)
{
L->data[k] = L->data[k - 1];
}
//插入元素
L->data[0] = e;
L->length++;
}
//頭刪,刪除順序表中的第一個元素,把順序表中的元素依次往前移動一位
void PopFront(PSeqList L)
{
if (EmptyList(L))
{
printf("順序表爲空,不能插入!\n");
}
for (k = 1; k <= L->length - 1; k++)
{
L->data[k - 1] = L->data[k];
}
L->length--;
}
//尾插
void PushBack(PSeqList L, DataType e)
{
if (L->length == ListSize)
{
printf("順序表已滿,不能插入!\n");
}
L->data[L->length] = e;
L->length++;
}
//尾刪
void PopBack(PSeqList L)
{
if (EmptyList(L))
{
printf("表爲空!\n");
}
L->length--;
}
//清空順序表
void ClearList(PSeqList L)
{
L->length = 0;
}
//判斷表是否爲空
int EmptyList(PSeqList L)
{
if (L->length == 0)
{
return 1;
}
return 0;
}
//打印表中元素
void PrintList(PSeqList L)
{
if (EmptyList(L))
{
printf("表爲空!\n");
return;
}
for (k = 0; k < L->length; k++)
{
printf("%-3d", L->data[k]);
}
printf("\n");
}
mian.c函數的簡單測試代碼
#include <stdio.h>
#include <Windows.h>
#include "SeqList.h"
int main()
{
SeqList L;
DataType data;
//初始化順序表
InitList(&L);
//在表中插入元素
printf("依次在表中插入元素(1,2,3,4,5):\n");
InsList(&L, 1, 1);
InsList(&L, 2, 2);
InsList(&L, 3, 3);
InsList(&L, 4, 4);
InsList(&L, 5, 5);
//打印表中元素
printf("表中元素有:\n");
PrintList(&L);
//頭插
printf("在表頭依次插入元素,6,7:\n");
PushFront(&L, 6);
PushFront(&L, 7);
//尾插
printf("在表尾依次插入元素,8,9:\n");
PushBack(&L, 8);
PushBack(&L, 9);
printf("表中元素有:\n");
PrintList(&L);
//頭刪
printf("頭刪一個元素:\n");
PopFront(&L);
//尾刪
printf("尾刪一個元素:\n");
PopBack(&L);
//輸出表中第4個元素值
PrintList(&L);
printf("表中第4個元素值爲:\n%d\n",GetData(&L, 4));
//查找表中第 i個元素的位置
printf("元素2在表中的位置爲:\n");
printf("%d\n",Locate(&L, 2));
//刪除表中第2個元素對應的值
printf("刪除表中第2個元素:%d\n", DelList(&L, 2, &data));
printf("順序表的長度爲:%d\n", LengthList(&L));
printf("表中元素爲:\n");
PrintList(&L);
//printf("刪除的元素值爲:%d\n", data);
//清空順序表
ClearList(&L);
PrintList(&L);
system("pause");
return 0;
}
---------------------
作者:LiuBo_01
來源:CSDN
原文:https://blog.csdn.net/liubo_01/article/details/80186552