線性表的順序表示和實現
線性表的順序表示指的是用一組地址連續的存儲單元依次存儲線性表的數據元素,這種表示也稱作線性表的順序存儲結構或者順序映像。通常,稱這種存儲結構的線性表為順序表。其特點是,邏輯上相鄰的數據元素,其物理次序也是相鄰的。
假設線性表的每個元素需占用L個存儲單元,並以所占的第一個單元的存儲地址作為數據元素的存儲起始位置。則線性表中第i+1個數據存儲位置LOC(ai+1)和第i個數據元素的存儲位置LOC(ai)之間滿足下列關系式:
LOC(ai+1)=LOC(ai)+L
一般來說,線性表的第i個數據元素ai的存儲位置為:LOC(ai)=LOC(ai)+(i - 1)*L,式中,LOC(ai)是線性表的第一個數據元素a1的存儲位置,通常稱為線性表的起始位置或基地址,表中相鄰的元素ai和ai+1的存儲位置LOC(ai)和LOC(ai+1)是相鄰的。每一個數據元素的存儲位置都和線性表的起始位置相差一個常數,這個常數和數據元素在線性表中的位序成正比。
由此,只要確定了存儲線性表的起始位置,線性表中任一數據元素都可隨機存取,所以線性表的順序存儲結構是一種隨機存取的存儲結構。
代碼部分:
首先定義一個結構體用來表示線性表
#define MAXSIZE 100 //最大長度 typedef struct //線性表的結構體 { ElemType *elem; //線性表 int lenth; //已存線性表長度 int listsize; //線性表總長度 }Sqlist;
初始化線性表,利用malloc函數動態申請分配內存,並設置了線性表長度為0和最大長度為100
int InitList(Sqlist &L) //初始化線性表 { L.elem = (ElemType *)malloc(100*sizeof(ElemType)); //動態分配線性表長度 if(!L.elem) //若未申請成功,則返回失敗 { return ERROR; } L.lenth = 0; //若申請成功,輸出線性表長度和總長度 L.listsize = 100; }
下面這個函數用來取某個元素,首先我們要取的那個數的下標判斷是否越界,越界就返回錯誤,沒越界的話,就將L.elem[i - 1]的值賦給e,為什么是i - 1呢?因為數組的下標是從0開始。
ElemType Getelem(Sqlist L,int i,ElemType &e) //取元素 { if(i < 1||i > L.lenth) //若越界,則返回錯誤 { return ERROR; } e = L.elem[i - 1]; //將取得的值賦給e return e; }
下面這個函數是用來插入元素的,首先判斷我們要插入的位置是否合理,如果小於1或者大於線性表的最大長度,就無法插入,同時呢,要判斷線性表是否存滿,已存滿的話也是沒辦法再存了的。上述情況都沒有的話,就可以插了,首先將線性表的最后一位下標得到,開始從最后一位,往后移一位,當移到我們要插入元素的那個地方后,將e賦值到這個位置即可,同時呢,線性表的長度也要自增1。
ElemType Insertelem(Sqlist &L,int i,ElemType e) //插入元素 { if(i < 1||i > L.lenth + 1) //判斷是否越界 { return ERROR; } if(L.lenth == 100) //判斷線性表是否已滿 { return ERROR; } for(int j = L.lenth - 1;j >= i - 1;j--) //從最后一位開始,向后移動 { L.elem[j + 1] = L.elem[j]; } L.elem[i - 1] = e; //插入 ++L.lenth; //線性表長度自增 return OK; }
下面這個函數是用來尋找某個元素的,這個比較容易實現,只需遍歷線性表,找到相等的值之后,就返回下標。
int Findelem(Sqlist L,ElemType elem) //尋找某個元素 { for(int i = 0;i < L.lenth;i++) //遍歷線性表,若成功則返回下標 { if(elem == L.elem[i]) { return (i+1); } } return ERROR; //未找到,返回失敗 }
這個函數用來輸出線性表,只需一個for循環遍歷線性表即可。
void PrintList(Sqlist L) //遍歷線性表,輸出線性表每個元素 { for(int i = 0;i < L.lenth;i++) { cout<<L.elem[i]; if(i != L.lenth - 1) { cout<<"-->"; } } cout<<endl; }
下面這個函數用來刪除某個位置的元素,首先,老規矩,判斷是否越界,然后將位置賦給j,再將后面的元素都前移一位。
int Delelem(Sqlist &L,int i) //刪除某個元素 { if(i < 1|| i > L.lenth + 1) //判斷是否越界 { return ERROR; } for(int j = i - 1;j < L.lenth;j++) //將該元素后面的元素諸位前移一位 { L.elem[j] = L.elem[j + 1]; } L.lenth--; //長度減一 }
這里我直接做了一個小小的功能程序,里面可以通過菜單分別執行上面的幾個函數。
#include <iostream> using namespace std; #include <stdio.h> #include<malloc.h> //動態分配內存的頭文件 #define OK 1 //成功 #define ERROR 0 //失敗 #define ElemType int //元素類型 #define MAXSIZE 100 //最大長度 typedef struct //線性表的結構體 { ElemType *elem; //線性表 int lenth; //已存線性表長度 int listsize; //線性表總長度 }Sqlist; int InitList(Sqlist &L) //初始化線性表 { L.elem = (ElemType *)malloc(100*sizeof(ElemType)); //動態分配線性表長度 if(!L.elem) //若未申請成功,則返回失敗 { return ERROR; } L.lenth = 0; //若申請成功,輸出線性表長度和總長度 L.listsize = 100; } ElemType Getelem(Sqlist L,int i,ElemType &e) //取元素 { if(i < 1||i > L.lenth) //若越界,則返回錯誤 { return ERROR; } e = L.elem[i - 1]; //將取得的值賦給e return e; } ElemType Insertelem(Sqlist &L,int i,ElemType e) //插入元素 { if(i < 1||i > L.lenth + 1) //判斷是否越界 { return ERROR; } if(L.lenth == 100) //判斷線性表是否已滿 { return ERROR; } for(int j = L.lenth - 1;j >= i - 1;j--) //從最后一位開始,向后移動 { L.elem[j + 1] = L.elem[j]; } L.elem[i - 1] = e; //插入 ++L.lenth; //線性表長度自增 return OK; } int Findelem(Sqlist L,ElemType elem) //尋找某個元素 { for(int i = 0;i < L.lenth;i++) //遍歷線性表,若成功則返回下標 { if(elem == L.elem[i]) { return (i+1); } } return ERROR; //未找到,返回失敗 } void PrintList(Sqlist L) //遍歷線性表,輸出線性表每個元素 { for(int i = 0;i < L.lenth;i++) { cout<<L.elem[i]; if(i != L.lenth - 1) { cout<<"-->"; } } cout<<endl; } int Delelem(Sqlist &L,int i) //刪除某個元素 { if(i < 1|| i > L.lenth + 1) //判斷是否越界 { return ERROR; } for(int j = i - 1;j < L.lenth;j++) //將該元素后面的元素諸位前移一位 { L.elem[j] = L.elem[j + 1]; } L.lenth--; //長度減一 } void Menu() //菜單函數 { cout<<"<<<<<<<<<<<<<<<<<<菜單>>>>>>>>>>>>>>>>>>"<<endl; cout<<"1.初始化線性表"<<endl; cout<<"2.取出線性表中的某個數"<<endl; cout<<"3.在線性表的某個位置插入元素"<<endl; cout<<"4.在線性表中尋找某個元素"<<endl; cout<<"5.刪除某個元素"<<endl; cout<<"6.輸出線性表"<<endl; cout<<"7.菜單"<<endl; cout<<"輸入對應選項,執行對應操作"<<endl; cout<<"初始線性表:"; } int main() { int choose; //元素位置序號 ElemType ea; //定義一個元素 Sqlist La; //定義一個線性表 InitList(La); //初始化線性表 Menu(); //輸出菜單 for(int i;i <= 10;i++) //用插入線性表函數給鏈表賦初值 { Insertelem(La,i,i); } PrintList(La); //輸出初始線性表 while(cin>>choose) //循環執行,選擇對應的選項,執行對應的操作 { switch(choose) { case 1: { InitList(La); cout<<"初始化線性表之后,線性表為空,請重新插入元素之后再進行操作"<<endl; int i,j; cout<<"輸入你要插入得位置和要插入的數:"; cin>>i>>j; Insertelem(La,i,j); cout<<"插入成功!"<<endl; break; } case 2: { int i; cout<<"輸入你要取得元素序號:"; cin>>i; cout<<Getelem(La,i,ea)<<endl; break; } case 3: { int i,j; cout<<"輸入你要插入得位置和要插入的數:"; cin>>i>>j; Insertelem(La,i,j); cout<<"插入成功!"<<endl; break; } case 4: { int pos,i; cout<<"輸入你要尋找的元素值:"; cin>>i; pos = Findelem(La,i); cout<<pos<<endl; break; } case 5: { int i; cout<<"請輸入你要刪除元素的下標:"; cin>>i; Delelem(La,i); cout<<"刪除成功!"<<endl; PrintList(La); break; } case 6:PrintList(La);break; case 7:Menu();break; default:cout<<"輸入有誤,請重新輸入"<<endl; } } return 0; }
運行結果:
大家有什么不懂的可以通過QQ(1033278524)來問我,碼字不易,希望大家能給我一個贊,支持一下,謝謝