C語(yǔ)言超詳細(xì)講解順序表的各種操作
順序表是什么
順序表是在計(jì)算機(jī)內(nèi)存中以數(shù)組的形式保存的線(xiàn)性表,線(xiàn)性表的順序存儲(chǔ)是指用一組地址連續(xù)的存儲(chǔ)單元依次存儲(chǔ)線(xiàn)性表中的各個(gè)元素、使得線(xiàn)性表中在邏輯結(jié)構(gòu)上相鄰的數(shù)據(jù)元素存儲(chǔ)在相鄰的物理存儲(chǔ)單元中,即通過(guò)數(shù)據(jù)元素物理存儲(chǔ)的相鄰關(guān)系來(lái)反映數(shù)據(jù)元素之間邏輯上的相鄰關(guān)系,采用順序存儲(chǔ)結(jié)構(gòu)的線(xiàn)性表通常稱(chēng)為順序表。順序表是將表中的結(jié)點(diǎn)依次存放在計(jì)算機(jī)內(nèi)存中一組地址連續(xù)的存儲(chǔ)單元中。
?
總的來(lái)說(shuō),順序表類(lèi)似于數(shù)組,下標(biāo)對(duì)應(yīng)的是相應(yīng)的元素(如圖所示)
順序表的結(jié)構(gòu)體
typedef struct
{
SLDataType *a;
int size;//表示數(shù)組中存儲(chǔ)了多少個(gè)數(shù)據(jù)
int capacity;//數(shù)組實(shí)際存儲(chǔ)數(shù)據(jù)的空間容量是多大
}SL;其中的SLDataType*a的意思是可以動(dòng)態(tài)開(kāi)辟空間--相當(dāng)于數(shù)組,因?yàn)閿?shù)組表示的是首元素的地址,這里是直接換成了指針,也指的是地址和數(shù)組的意思一樣!
typedef int SLDataType;//重命名,到時(shí)候方便更改類(lèi)型
順序表的接口函數(shù)
void menu();//菜單
void SeqListInit(SL*ps);//初始化
void SeqListPushBack(SL*ps, SLDataType x);//往后加元素
void SeqListPush(SL*ps, SLDataType n);//在順序表中添加元素
void SeqListPopBack(SL*ps);//刪除最后一個(gè)元素
void SeqListPushFront(SL*ps, SLDataType x);//往前面加元素
void SeqListPopFront(SL*ps);//刪除第一個(gè)元素
void SepListdisplay(SL*ps);//陳列
void SeqListPushMid(SL*ps, SLDataType x,SLDataType z);//往中間加元素
void SeqListPopMid(SL*ps,SLDataType x);//刪除中間某一個(gè)元素
這里只是先對(duì)一些函數(shù)進(jìn)行聲名,還沒(méi)有進(jìn)行創(chuàng)建函數(shù)!
順序表相關(guān)操作的菜單
void menu()
{
cout << "\t\t\t******************************************************************" << endl;
cout << "\t\t\t**************** 注意!每次都要先進(jìn)行初始化 *******************" << endl;
cout << "\t\t\t**************** 1.輸入-1 退出程序 *******************" << endl;
cout << "\t\t\t**************** 2.輸入1 初始化 *******************" << endl;
cout << "\t\t\t**************** 3.輸入2 添加元素 *******************" << endl;
cout << "\t\t\t**************** 4.輸入3 陳列元素 *******************" << endl;
cout << "\t\t\t**************** 5.輸入4 往最后加元素 *******************" << endl;
cout << "\t\t\t**************** 6.輸入5 往前面加元素 *******************" << endl;
cout << "\t\t\t**************** 7.輸入6 任意位置加元素 *******************" << endl;
cout << "\t\t\t**************** 8.輸入7 刪除最后元素 *******************" << endl;
cout << "\t\t\t**************** 8.輸入8 刪除前面元素 *******************" << endl;
cout << "\t\t\t**************** 8.輸入9 刪除任意元素 *******************" << endl;
cout << "\t\t\t******************************************************************" << endl;
}可以在控制臺(tái)輸入相關(guān)的數(shù)字進(jìn)行相關(guān)的操作
順序表的初始化
void SeqListInit(SL*ps)//初始化
{
ps->a = NULL;
ps->size = ps->capacity = 0;
cout << "初始化完成" << endl;
}順序表初始化,首先使順序表的指針置為空,先讓順序表的長(zhǎng)度和容量都先置為空
添加元素
void SeqListPush(SL*ps, SLDataType n)
{
if (ps->size == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 100 : ps->capacity * 2;
SLDataType*tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));//SLDataType類(lèi)型(強(qiáng)制類(lèi)型轉(zhuǎn)換)的有newcapacity大小的空間
if (tmp == NULL)
{
cout << "分配失敗" << endl;
exit(-1);
}
ps->a = tmp;
ps->capacity = newcapacity;
}
int k = 0;
cout << "請(qǐng)進(jìn)行賦值" << endl;
for (int i = 0; i < n; i++)
{
cin >> k;
ps->a[i] = k;
ps->size++;
}
cout << "賦值完成" << endl;
}此時(shí)先進(jìn)行判斷,如果沒(méi)有空間或者空間不足,就要把把一個(gè)新的容量賦值為原來(lái)容量的二倍,如果是0就賦值為100 。relloc是擴(kuò)容函數(shù),是在ps->a后面擴(kuò)容一個(gè)SLDataType類(lèi)型(強(qiáng)制類(lèi)型轉(zhuǎn)換)的有newcapacity大小的空間,申請(qǐng)成功的話(huà),就讓指針a的地址存放新的地址tmp,此時(shí)新的地址tmp里面有擴(kuò)容后的空間,再讓capacity為新的容量,讓ps的第一個(gè)位置放傳進(jìn)來(lái)函數(shù)的x,最后再讓它的大小++。
陳列元素
void SepListdisplay(SL*ps)//陳列
{
cout << "下面是您賦值的元素" << endl;
for (int i = 0; i < ps->size; i++)
{
cout << ps->a[i] << " ";
}
cout << endl;
}陳列元素這塊很簡(jiǎn)單,直接可以通過(guò)它的下標(biāo)找到它所代表的值,跟數(shù)組一樣
往最后加元素
void SeqListPushBack(SL*ps, SLDataType x)
{
if (ps->size == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 100 : ps->capacity * 2;
SLDataType*tmp = (SLDataType*)realloc(ps->a, newcapacity*sizeof(SLDataType));
if (tmp == NULL)//如果分配失敗
{
cout << "分配失敗" << endl;
exit(-1);
}
ps->a = tmp;
ps->capacity = newcapacity;
}
ps->a[ps->size] = x;
ps->size++;//再讓它的大小++
cout << "添加完成" << endl;
}此時(shí)還是要先進(jìn)行判斷順序表的空間夠不夠,要是空間不夠的話(huà),再運(yùn)用realloc函數(shù)進(jìn)行重新分配空間,再直接讓最后一個(gè)位置里面放上傳過(guò)來(lái)的元素就可以了。
往前面加元素
void SeqListPushFront(SL*ps, SLDataType x)
{
if (ps->size == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 100 : ps->capacity * 2;
SLDataType*tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));
if (tmp == NULL)
{
cout << "分配失敗" << endl;
exit(-1);
}
ps->a = tmp;
ps->capacity = newcapacity;
}
ps->size++;
int i = 0;
int j = ps->size;
for (i = j; i > 0; i--)
{
ps->a[i] = ps->a[i - 1];
}
ps->a[0] = x;
cout << "添加完成" << endl;
}往前面加元素的話(huà),首先還是需要進(jìn)行判斷空間夠不夠,要是不夠還是要運(yùn)用realloc函數(shù)重新分配空間,此時(shí)要是想要在最前面添加元素的話(huà),就需要先讓它的大小++,再讓從下標(biāo)為0的第一個(gè)元素開(kāi)始,把每一個(gè)元素都往后移動(dòng)一個(gè)位置。移動(dòng)完成之后,再讓新的元素加入的順序表的表頭就可以了。
任意位置加元素
void SeqListPushMid(SL*ps, SLDataType x,SLDataType z)
{
ps->size++;
int i = 0;
int j = ps->size - 1;
for (i=j; i >= x; i--)
{
ps->a[i + 1] = ps->a[i];
}
ps->a[x] = z;
cout << "添加完成" << endl;
}要是想在任意位置加元素的話(huà),我們首先應(yīng)該知道我們需要進(jìn)行加元素的下標(biāo),以及我們需要添加的元素,此時(shí)剛好我們的函數(shù)里面已經(jīng)接收到了這兩個(gè)元素,此時(shí)我們就從這個(gè)下標(biāo)開(kāi)始,讓下標(biāo)對(duì)應(yīng)的元素以及下標(biāo)之后的元素都往后加一個(gè)位置,此時(shí)就可以為新的元素騰出一個(gè)位置,等全部移動(dòng)完成后,我們就可以把元素加進(jìn)來(lái)就可以了。
刪除最后元素
void SeqListPopBack(SL*ps)//刪除最后一個(gè)元素
{
if (ps->size > 0)
{
ps->size--;
}
cout << "刪除完畢" << endl;
}這一塊是最簡(jiǎn)單的了,直接讓順序表的大小--就可以了。
刪除前面元素
void SeqListPopFront(SL*ps)//刪除第一個(gè)元素
{
int i = 0;
int j = ps->size;
for (i = 1; i < j ; i++)
{
ps->a[i-1] = ps->a[i];
}
ps->size--;
cout << "刪除完畢" << endl;
}我們這里可以直接讓從下標(biāo)為1以及后面的元素的位置往前面加一個(gè)位置,把第一個(gè)元素覆蓋住就可以了。
刪除任意元素
void SeqListPopMid(SL*ps, SLDataType x)//刪除中間某一元素
{
int i = 0, j = 0;
for (i = x; i < ps->size ; i++)
{
ps->a[i] = ps->a[i + 1];
}
ps->size--;
cout << "刪除完畢" << endl;
}這里的話(huà)我們已經(jīng)知道我們需要?jiǎng)h除元素的下標(biāo)了,于是我們就可以從這個(gè)下標(biāo)開(kāi)始不包括這個(gè)下標(biāo)對(duì)應(yīng)的元素 ,把它們的位置往前推一個(gè),把該元素覆蓋住就可以了,最后再讓大小減一。
整體代碼(fun.h部分)
#pragma once
#define N 10000
typedef int SLDataType;
typedef struct
{
SLDataType *a;
int size;
int capacity;
}SL;
//接口函數(shù)
void menu();//菜單
void SeqListInit(SL*ps);//初始化
void SeqListPushBack(SL*ps, SLDataType x);//往后加元素
void SeqListPush(SL*ps, SLDataType n);//在順序表中添加元素
void SeqListPopBack(SL*ps);//刪除最后一個(gè)元素
void SeqListPushFront(SL*ps, SLDataType x);//往前面加元素
void SeqListPopFront(SL*ps);//刪除第一個(gè)元素
void SepListdisplay(SL*ps);//陳列
void SeqListPushMid(SL*ps, SLDataType x,SLDataType z);//往中間加元素
void SeqListPopMid(SL*ps,SLDataType x);//刪除中間某一個(gè)元素整體代碼(fun.cpp部分)
#include<iostream>//順序表的實(shí)現(xiàn)
#include<stdlib.h>
#include"fun.h"
using namespace std;
void menu()
{
cout << "\t\t\t******************************************************************" << endl;
cout << "\t\t\t**************** 注意!每次都要先進(jìn)行初始化 *******************" << endl;
cout << "\t\t\t**************** 1.輸入-1 退出程序 *******************" << endl;
cout << "\t\t\t**************** 2.輸入1 初始化 *******************" << endl;
cout << "\t\t\t**************** 3.輸入2 添加元素 *******************" << endl;
cout << "\t\t\t**************** 4.輸入3 陳列元素 *******************" << endl;
cout << "\t\t\t**************** 5.輸入4 往最后加元素 *******************" << endl;
cout << "\t\t\t**************** 6.輸入5 往前面加元素 *******************" << endl;
cout << "\t\t\t**************** 7.輸入6 任意位置加元素 *******************" << endl;
cout << "\t\t\t**************** 8.輸入7 刪除最后元素 *******************" << endl;
cout << "\t\t\t**************** 8.輸入8 刪除前面元素 *******************" << endl;
cout << "\t\t\t**************** 8.輸入9 刪除任意元素 *******************" << endl;
cout << "\t\t\t******************************************************************" << endl;
}
void SeqListInit(SL*ps)//初始化
{
ps->a = NULL;
ps->size = ps->capacity = 0;
cout << "初始化完成" << endl;
}
void SeqListPush(SL*ps, SLDataType n)//在順序表中加元素
{
if (ps->size == ps->capacity)//如果沒(méi)有空間或者空間不足
{
int newcapacity = ps->capacity == 0 ? 100 : ps->capacity * 2;//把一個(gè)新的容量賦值為原來(lái)容量的二倍,如果是0就賦值為100
SLDataType*tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));//relloc是擴(kuò)容函數(shù),是在ps->a后面擴(kuò)容一個(gè)
//SLDataType類(lèi)型(強(qiáng)制類(lèi)型轉(zhuǎn)換)的有newcapacity大小的空間
if (tmp == NULL)//如果分配失敗
{
cout << "分配失敗" << endl;
exit(-1);
}
ps->a = tmp;//申請(qǐng)成功的話(huà),就讓指針a的地址存放新的地址tmp,此時(shí)新的地址tmp里面有擴(kuò)容后的空間
ps->capacity = newcapacity;//再讓capacity為新的容量
}
int k = 0;
cout << "請(qǐng)進(jìn)行賦值" << endl;
for (int i = 0; i < n; i++)
{
cin >> k;
ps->a[i] = k;
ps->size++;
}
cout << "賦值完成" << endl;
}
void SeqListPushBack(SL*ps, SLDataType x)//往后加元素,或者也可以叫做為順序表賦值
{
if (ps->size == ps->capacity)//如果沒(méi)有空間或者空間不足
{
int newcapacity = ps->capacity == 0 ? 100 : ps->capacity * 2;//把一個(gè)新的容量賦值為原來(lái)容量的二倍,如果是0就賦值為100
SLDataType*tmp = (SLDataType*)realloc(ps->a, newcapacity*sizeof(SLDataType));//relloc是擴(kuò)容函數(shù),是在ps->a后面擴(kuò)容一個(gè)
//SLDataType類(lèi)型(強(qiáng)制類(lèi)型轉(zhuǎn)換)的有newcapacity大小的空間
if (tmp == NULL)//如果分配失敗
{
cout << "分配失敗" << endl;
exit(-1);
}
ps->a = tmp;//申請(qǐng)成功的話(huà),就讓指針a的地址存放新的地址tmp,此時(shí)新的地址tmp里面有擴(kuò)容后的空間
ps->capacity = newcapacity;//再讓capacity為新的容量
}
ps->a[ps->size] = x;//讓ps的第一個(gè)位置放傳進(jìn)來(lái)函數(shù)的x
ps->size++;//再讓它的大小++
cout << "添加完成" << endl;
}
void SeqListPopBack(SL*ps)//刪除最后一個(gè)元素
{
if (ps->size > 0)
{
ps->size--;
}
cout << "刪除完畢" << endl;
}
void SeqListPushFront(SL*ps, SLDataType x)//往前面加元素
{
//進(jìn)來(lái)先判斷一下里面的空間滿(mǎn)沒(méi)有
if (ps->size == ps->capacity)//如果沒(méi)有空間或者空間不足
{
int newcapacity = ps->capacity == 0 ? 100 : ps->capacity * 2;//把一個(gè)新的容量賦值為原來(lái)容量的二倍,如果是0就賦值為100
SLDataType*tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));//relloc是擴(kuò)容函數(shù),是在ps->a后面擴(kuò)容一個(gè)
//SLDataType類(lèi)型的有newcapacity大小的空間
if (tmp == NULL)//如果分配失敗
{
cout << "分配失敗" << endl;
exit(-1);
}
ps->a = tmp;//申請(qǐng)成功的話(huà),就讓指針a的地址存放新的地址tmp,此時(shí)新的地址tmp里面有擴(kuò)容后的空間
ps->capacity = newcapacity;//再讓capacity為新的容量
}
ps->size++;
int i = 0;
int j = ps->size;
for (i = j; i > 0; i--)
{
ps->a[i] = ps->a[i - 1];
}
ps->a[0] = x;
cout << "添加完成" << endl;
}
void SeqListPopFront(SL*ps)//刪除第一個(gè)元素
{
int i = 0;
int j = ps->size;
for (i = 1; i < j ; i++)
{
ps->a[i-1] = ps->a[i];
}
ps->size--;
cout << "刪除完畢" << endl;
}
void SepListdisplay(SL*ps)//陳列
{
cout << "下面是您賦值的元素" << endl;
for (int i = 0; i < ps->size; i++)
{
cout << ps->a[i] << " ";
}
cout << endl;
}
void SeqListPushMid(SL*ps, SLDataType x,SLDataType z)//往中間加元素
{
ps->size++;
int i = 0;
int j = ps->size - 1;
for (i=j; i >= x; i--)
{
ps->a[i + 1] = ps->a[i];
}
ps->a[x] = z;
cout << "添加完成" << endl;
}
void SeqListPopMid(SL*ps, SLDataType x)//刪除中間某一元素
{
int i = 0, j = 0;
for (i = x; i < ps->size ; i++)
{
ps->a[i] = ps->a[i + 1];
}
ps->size--;
cout << "刪除完畢" << endl;
}整體代碼(主函數(shù)部分)
#include<iostream>//順序表的實(shí)現(xiàn)
#include<stdlib.h>
#include"fun.h"
using namespace std;
int main()
{
SL ps;
int n = 0, m = 0;
int x = 0;
menu();
while (cin >> x)
{
if (x < 0)
{
break;
}
switch (x)
{
case 1:
SeqListInit(&ps);
break;
case 2:
cout << "請(qǐng)輸入您要添加幾個(gè)元素" << endl;
cin >> n;
SeqListPush(&ps, n);
break;
case 3:
SepListdisplay(&ps);
break;
case 4:
cout << "請(qǐng)輸入您要在最后添加什么元素" << endl;
cin >> n;
SeqListPushBack(&ps, n);
break;
case 5:
cout << "請(qǐng)輸入您要在最前面添加什么元素" << endl;
cin >> n;
SeqListPushFront(&ps, n);
break;
case 6:
cout << "請(qǐng)輸入您要添加位置的下標(biāo)以及添加的元素" << endl;
cin >> n >> m;
SeqListPushMid(&ps, 1, 6);
break;
case 7:
SeqListPopBack(&ps);
break;
case 8:
SeqListPopFront(&ps);
break;
case 9:
cout << "請(qǐng)輸入您要進(jìn)行刪除元素的下標(biāo)" << endl;
cin >> n;
SeqListPopMid(&ps, n);
default:
cout << "您的輸入有誤,請(qǐng)重新輸入" << endl;
}
}
return 0;
}結(jié)果展示



到此這篇關(guān)于C語(yǔ)言超詳細(xì)講解順序表的各種操作的文章就介紹到這了,更多相關(guān)C語(yǔ)言順序表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)現(xiàn)inline hook的原理及應(yīng)用實(shí)例
這篇文章主要介紹了C++實(shí)現(xiàn)inline hook的原理及應(yīng)用,需要的朋友可以參考下2014-08-08
C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)中串的模式匹配
這篇文章主要介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)中串的模式匹配的相關(guān)資料,需要的朋友可以參考下2017-05-05
C++實(shí)現(xiàn)LeetCode(94.二叉樹(shù)的中序遍歷)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(94.二叉樹(shù)的中序遍歷),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
如何統(tǒng)計(jì)在一篇文章中某個(gè)單詞出現(xiàn)了幾次,以及第一次出現(xiàn)的位置
本文的主要內(nèi)容就是統(tǒng)計(jì)某個(gè)單詞在一篇文章中出現(xiàn)了幾次,以及第一次出現(xiàn)的位置,需要的朋友可以參考下2015-08-08
C語(yǔ)言實(shí)現(xiàn)動(dòng)態(tài)鏈表的示例代碼
本文主要介紹了C語(yǔ)言實(shí)現(xiàn)動(dòng)態(tài)鏈表的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05
Qt實(shí)現(xiàn)UDP多線(xiàn)程數(shù)據(jù)處理及發(fā)送的簡(jiǎn)單實(shí)例
本文主要介紹了Qt實(shí)現(xiàn)UDP多線(xiàn)程數(shù)據(jù)處理及發(fā)送的簡(jiǎn)單實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
c語(yǔ)言函數(shù)棧幀的創(chuàng)建和銷(xiāo)毀過(guò)程詳解
我們知道c語(yǔ)言中函數(shù)都是被調(diào)用的,main函數(shù)里面能調(diào)用其他函數(shù),其實(shí)main函數(shù)也是被別的函數(shù)調(diào)用的,下面通過(guò)本文給大家分享c語(yǔ)言函數(shù)棧幀的創(chuàng)建和銷(xiāo)毀過(guò)程,一起看看吧2021-08-08
Qt實(shí)現(xiàn)簡(jiǎn)單折線(xiàn)圖表
這篇文章主要為大家詳細(xì)介紹了Qt實(shí)現(xiàn)簡(jiǎn)單折線(xiàn)圖表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06
詳解C++中stoi/stol/stoll函數(shù)的用法
這篇文章主要為大家詳細(xì)介紹了C++中stoi、stol、stoll函數(shù)的具體用法,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)校C++有一點(diǎn)的幫助,需要的可以參考一下2023-03-03

