线性表(一)——顺序表
線性表(一)
線性表(linear list),也稱有序表(ordered list),是線性結構的典型代表。數據元素之間僅具有單一的前驅和后繼關系。
一、線性表的邏輯結構
1.線性表的定義
線性表簡稱表,是n(n≥0)個具有相同類型的數據元素的有限序列,線性表中數據元素的個數稱為線性表的長度。長度等于零時稱為空表,一個非空表通常記為:
L = (a1,a2,···,an)
ai-1 稱為ai的前驅,ai 稱為ai-1的后繼。
2.線性表的抽象數據結構定義
ADT LinearList {Data有限個元素的集合OperationInitList():線性表不存在,初始化,生成一個空表Empty():若表為空,返回true,否則返回falseLength():返回線性表的大小(表的元素個數)Get(index):返回線性表中索引為index的元素IndexOf(x):返回線性表中第一次出現的元素x的索引。若x不存在,則返回-1Insert(index,x):把x插入線性表中索引為index的位置上,索引大于等于index的元素其索引加1Erase(index):刪除索引為index的元素,索引大于index的元素其索引減1DestroyList():銷毀線性表,釋放所有內存PrintList():遍歷輸出線性表中的所有元素} endADT二、線性表的存儲結構及實現
1.線性表——數組描述
線性表的順序存儲結構稱為順序表(sequential list)。順序表是用一段地址連續的存儲單元依次存儲線性表的數據元素。由于線性表中的每個數據元素的類型相同,通常用一維數組來實現順序表。
順序表存儲數據時,會提前申請一整塊足夠大小的物理空間,然后將數據依次存儲起來,存儲時做到數據元素之間不留一絲縫隙。
使用順序表存儲數據之前,除了要申請足夠大小的物理空間之外,為了方便后期使用表中的數據,順序表還需要實時記錄以下 2 項數據:
因為在線性表中可以進行插入操作,順序表申請的存儲容量要大于順序表的長度。
自定義順序表
typedef struct Table{int * head;//聲明了一個名為head的長度不確定的數組,也叫“動態數組”int length;//記錄當前順序表的長度int size;//記錄順序表分配的存儲容量 }table;順序表的初始化
#define Size 5 //對Size進行宏定義,表示順序表申請空間的大小 table initTable(){table t;t.head=(int*)malloc(Size*sizeof(int));//構造一個空的順序表,動態申請存儲空間if (!t.head) //如果申請失敗,作出提示并直接退出程序{printf("初始化失敗");exit(0);}t.length=0;//空表的長度初始化為0t.size=Size;//空表的初始存儲空間為Sizereturn t; }輸出順序表中的元素
//輸出順序表中元素的函數 void displayTable(table t){for (int i=0;i<t.length;i++) {printf("%d ",t.head[i]);}printf("\n"); }順序表插入元素
向已有順序表中插入數據元素,根據插入位置的不同,可分為以下 3 種情況:
雖然數據元素插入順序表中的位置有所不同,但是都使用的是同一種方式去解決,即:通過遍歷,找到數據元素要插入的位置,然后做如下兩步工作:
- 將要插入位置元素以及后續的元素整體向后移動一個位置;
- 將元素放到騰出來的位置上;
動態數組額外申請更多物理空間使用的是 realloc 函數。
順序表刪除元素
從順序表中刪除指定元素,實現起來非常簡單,只需找到目標元素,并將其后續所有元素整體前移 1 個位置即可。(后續元素整體前移一個位置,會直接將目標元素刪除,可間接實現刪除元素的目的。)
table DelTable(table t,int index){if (index>t.length || index<1) {printf("被刪除元素的位置有誤\n");return t;}//刪除操作for (int i=index; i<t.length; i++) {t.head[i-1]=t.head[i];}t.length--;return t; }順序表查找元素
//順序查找算法查找目標元素 //查找函數,其中,elem表示要查找的數據元素的值 int IndexOf(table t,int elem){for (int i=0; i<t.length; i++) {if (t.head[i]==elem) {return i+1;}}return -1;//如果查找失敗,返回-1 }順序表更改元素
順序表更改元素的實現過程是:
線性表完整實現代碼:
#include <stdio.h> #include <stdlib.h>typedef int elemType; #define SIZE 10 //對SIZE進行宏定義,表示順序表申請空間的大小//定義順序表的結構 typedef struct Table {elemType *head; //聲明了一個名為head的長度不確定的數組,也叫“動態數組”int length; //記錄當前順序表的長度int size; //記錄順序表分配的存儲容量 }table;//順序表初始化,創建一個空表,返回表頭地址 table InitTable() {table t;t.head = (elemType)malloc(SIZE * sizeof(elemType)); //動態申請動態內存if(!t.head) //如果申請失敗,作出提示并直接退出程序{printf("初始化失敗");exit(0);}t.length = 0; //空表的長度初始化為0t.size = SIZE; //空表的初始存儲空間為SIZEreturn t; }//輸出順序表中元素的函數 void PrintTable(table t){for (int i=0;i<t.length;i++) {printf("%d ",t.head[i]);}printf("\n"); }//插入函數,其中,elem為插入的元素,index為插入到順序表的位置 table Insert(table t,elemType elem,int index) {//判斷插入本身是否存在問題(如果插入元素位置比整張表的長度+1還大(如果相等,是尾隨的情況),//或者插入的位置本身不存在,程序作為提示并自動退出)if(index>t.length+1||index<1){printf("插入位置有問題");return t;}//做插入操作時,首先需要看順序表是否有多余的存儲空間提供給插入的元素,如果沒有,需要申請if (t.length==t.size){t.head=(int *)realloc(t.head, (t.size+1)*sizeof(elemType));if (!t.head){printf("存儲分配失敗\n");return t;}t.size+=1;}//插入操作,需要將從插入位置開始的后續元素,逐個后移for (int i=t.length-1; i>=index-1; i--) {t.head[i+1]=t.head[i];}//后移完成后,直接將所需插入元素,添加到順序表的相應位置t.head[index-1]=elem;//由于添加了元素,所以長度+1t.length++;return t; }//順序表刪除元素 table DelTable(table t,int index) {if (index>t.length || index<1) {printf("被刪除元素的位置有誤\n");return t;}//刪除操作for(int i=index; i<t.length; i++) {t.head[i-1]=t.head[i];}t.length--;return t; } //查找函數,其中,elem表示要查找的數據元素的值 int IndexOf(table t,elemType elem) {for (int i=0; i<t.length; i++){if (t.head[i]==elem){return i+1;}}return -1;//如果查找失敗,返回-1 }//更改函數,其中,elem為要更改的元素,newElem為新的數據元素 table AlterTable(table t,elemType elem,elemType newElem) {int index=IndexOf(t, elem);t.head[index-1]=newElem;//由于返回的是元素在順序表中的位置,所以index-1就是該元素在數組中的下標return t; }int main() {table t1=InitTable();for (int i=1; i<=SIZE; i++) {t1.head[i-1]=i;t1.length++;}printf("原順序表:\n");PrintTable(t1);printf("刪除元素1:\n");t1=DelTable(t1, 1);PrintTable(t1);printf("在第2的位置插入元素5:\n");t1=Insert(t1, 5, 2);PrintTable(t1);printf("查找元素3的位置:\n");int index=IndexOf(t1, 3);printf("%d\n",index);printf("將元素3改為6:\n");t1=AlterTable(t1, 3, 6);PrintTable(t1);return 0; }運行結果:
原順序表: 1 2 3 4 5 6 7 8 9 10 刪除元素1: 2 3 4 5 6 7 8 9 10 在第2的位置插入元素5: 2 5 3 4 5 6 7 8 9 10 查找元素3的位置: 3 將元素3改為6: 2 5 6 4 5 6 7 8 9 10上一篇:數據結構基本概念
下一篇:線性表(二)—— 鏈表
總結
以上是生活随笔為你收集整理的线性表(一)——顺序表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 线性表(二)——链表
- 下一篇: HTML内嵌式CSS背景图填充满无截断重