線性表的實現及其基本操作
阿新 • • 發佈:2018-12-24
- 線性表的定義
線性表是最簡單最常用的一種資料結構,它是一種能在任意位置進行插入和刪除資料元素操作的、由n(n>=0)個相同資料元素組成的線性結構。 - 線性表的抽象資料型別
資料集合
線性表的資料集合可以表示為a0, a1, a2, a3, ……, an-1,每個資料元素的資料型別都是抽象資料元素的資料型別ElemType。
操作集合(在此僅羅列一部分,詳細內容請看程式碼塊)
a. 初始化 InitiateList(L):初始化線性表L
b. 求當前資料元素個數ListLebgth(L)
c. 插入資料元素ListInset(L, i, x): 線上性表L的第i個數據元素前插入資料元素x
d. 刪除資料元素ListDelete(L, i, x):刪除線性表第i個數據元素x
e. 取資料元素ListGet(L, i, x): 取線性表的第i個數據元素x
//順序表相關操作標頭檔案
#define ElemType int
#include<malloc.h>
#include<string.h>
#define SIZE 10
#define NEWSIZE 4
typedef struct SeqList
{
ElemType *base; //順序表空間,指的是為順序表在記憶體中動態申請的空間
size_t capacity; //順序表的容量
size_t length; //順序表的長度,即元素的個數
}SeqList;
int NewSpace(SeqList *list ) //尾插時需要申請新的空間
{
ElemType *newspace = (ElemType*)malloc(sizeof(ElemType)*(list->capacity + NEWSIZE));
if(newspace == NULL)
{
printf("Out Of Memory!\n");
return 0;
}
memcpy(newspace, list->base, sizeof(ElemType)*list->capacity); //將新申請的空間作為新的順序表空間,並且將原來的順序表空間釋放
free(list->base);
list->base = newspace;
list->capacity += NEWSIZE;
return 1;
}
void InitSeqList(SeqList *list) //順序表的初始化
{
list->capacity = SIZE;
list->base = (ElemType *)malloc(sizeof(ElemType)*list->capacity);
list->length = 0;
}
int BegInsert(SeqList *list, ElemType a) //頭插元素
{
if(list->length >= list->capacity) //判斷順序表的長度是否大於容量
{
printf("空間已滿,不能插入!\n");
return 0;
}
if(NULL == list->base) //判斷順序表是否被置空 如果已經置空就不能插入資料
{
printf("out of memory\n");
return 0;
}
for(int i=list->length; i>0; i--)
{
list->base[i] = list->base[i-1];
}
list->base[0] = a;
list->length++;
return 1;
}
int EndInsert(SeqList *list, ElemType a) //尾插元素
{
if(NULL == list->base) //判斷順序表是否被置空 如果已經置空就不能插入資料
{
printf("out of memory\n");
return 0;
}
if(list->length >= list->capacity && !NewSpace(list)) //判斷插入後順序表的長度是否大於容量,是否與新申請的空間大小不符
{
printf("空間已滿,無法插入!\n");
return 0;
}
list->base[list->length++] = a; //把插入的值賦給順序表增加的新空間
return 1;
}
void ShowList(SeqList *list) //順序表的顯示
{
for(int i=0; i<list->length; i++)
{
printf("%d ",list->base[i]);
printf(" ");
}
printf("\n");;
}
int BegDelete(SeqList *list) // 頭刪元素
{
if(list->length == 0) // 判斷是否非空
{
printf("順序表已空,無資料可刪!\n");
return 0;
}
for(int i=0; i<list->length-1; i++) // 頭刪只需讓順序表中的元素從後往前逐個移動
{
list->base[i] = list->base[i+1];
}
list->length--;
return 1;
}
int EndDelete(SeqList *list) //尾刪元素
{
if(list->length == 0)
{
printf("順序表已空,無資料可刪!\n");
return 0;
}
list->length--; // 尾部刪除只需將順序表的長度減一即可
return 1;
}
void SortList(SeqList *list) //對順序表內的資料排序----氣泡排序法
{
int i, j;
for(i=0; i<list->length; i++)
{
for(j=0; j<list->length-i-1; j++)
{
if(list->base[j] > list->base[j+1])
{
int temp = list->base[j];
list->base[j] = list->base[j+1];
list->base[j+1] = temp;
}
}
}
}
int InsertBVal(SeqList *list, ElemType a) //在順序表中按值插入資料
{
if(list->length >= list->capacity) //判斷順序表的長度是否大於容量
{
printf("空間已滿,不能插入!\n");
return 0;
}
if(list->length == 0) //如果順序表是空的,則將插入的值當做第一個數
{
list->base[0] = a;
}
else
{
int pos;
for(pos=0; pos<list->length; pos++)
{
if(list->base[pos] > a) // 找到pos的位置然後跳出
break;
}
for(int i=list->length; i>pos; i--)
{
list->base[i] = list->base[i-1];
}
list->base[pos] = a;
}
list->length++;
return 1;
}
int InsertBPos(SeqList *list, int pos, ElemType a) //按照位置插入資料
{
if(list->length >= list->capacity) //判斷順序表的長度是否大於容量
{
printf("空間已滿,不能插入!\n");
return 0;
}
if(pos<0 || pos>list->length)
{
printf("插入元素位置出錯!\n");
return 0;
}
for(int i=list->length; i>pos; i--) //找出pos的位置,然後將pos到順序表末尾的資料逐個向後移動,最後在pos處將a插入
{
list->base[i] = list->base[i-1];
}
list->base[pos] = a;
list->length++;
return 1;
}
int DelByPos(SeqList *list, int pos) //按照位置刪除元素
{
int i;
if(list->length == 0)
{
printf("順序表已空,無資料可刪!\n");
return 0;
}
for(i=0; i<pos; i++)
{
if(i == pos)
break;
}
for(i=pos; i<list->length; i++)
{
list->base[i] = list->base[i+1];
}
list->length--;
return 1;
}
int DelByValue(SeqList *list, ElemType a) // 根據數值刪除順序表中的元素
{
int i, j;
if(list->length == 0)
{
printf("順序表已空,無資料可刪!\n");
return 0;
}
for(i=0; i<list->length; i++)
{
if(list->base[i] == a) // 找到要刪除的資料
break;
}
for(j=i; j<list->length; j++) //將要刪除的資料之後的資料逐個向前移動
{
list->base[j] = list->base[j+1];
}
list->length--;
return 1;
}
void FindElem(SeqList *list, ElemType a) //查詢順序表中的某一資料
{
int i;
if(list->length ==0)
{
printf("順序表為空,沒有資料!\n");
return;
}
else
{
for(i=0; i<list->length; i++)
{
if(list->base[i] == a) //找到要查詢的資料的位置跳出迴圈,輸出結果
break;
}
printf("該資料在順序表的%d的位置處\n",i);
}
}
int ListLength(SeqList *list) //求順序表中的資料個數
{
printf("該順序表中有%d個數據\n",list->length); // 將順序表的長度打印出來即可
return 1;
}
void CleanList(SeqList *list) //順序表的清空, 讓順序表的長度為零即可
{
if(list->length == 0)
{
printf("順序表為空!\n");
}
else
{
list->length = 0;
printf("順序表已清空!\n");
}
}
void ReverseShow(SeqList *list) //順序表的逆序輸出
{
if(list->length == 0)
{
printf("順序表為空!\n");
}
else
{
for(int i=list->length-1; i>=0; --i) //注意迴圈條件 順序表的下標從0開始
{
printf("%d ",list->base[i]);
}
printf("\n");
}
}
void DestroyList(SeqList *list) //順序表的銷燬
{
free(list->base); //順序表的記憶體是連續的,只需要將它的空間釋放後再置空就行
list->base = NULL;
}
#include<stdio.h>
#include"SeqList.h"
//順序表操作測試
void main()
{
SeqList list;
InitSeqList(&list);
ElemType x;
int pos;
int select = 1;
while(select)
{
printf("*************************************************\n");
printf("*[1] BegInsert [2] EndInsert [3] ShowList *\n");
printf("*[4] BegDelete [5] EndDelete [6] SortList *\n");
printf("*[7] InsertBPos [8] InsertBVal [9] DelByPos *\n");
printf("*[10]DelByValue [11]FindElem [12]ListLength *\n");
printf("*[13]CleanList [14]ReverseShow [15]DestroyList*\n");
printf("*************** [0] QuitSystem ******************\n");
printf("*************************************************\n");
printf("請選擇: ");
scanf("%d",&select);
switch(select)
{
case 0:
break;
case 1:
printf("請輸入要插入的資料(以-1結束):> ");
while(scanf("%d",&x),x != -1)
{
BegInsert(&list, x);
}
break;
case 2:
printf("請輸入要插入的資料(以-1結束):> ");
while(scanf("%d",&x),x != -1)
{
EndInsert(&list, x);
}
break;
case 3:
ShowList(&list);
break;
case 4:
BegDelete(&list);
break;
case 5:
EndDelete(&list);
break;
case 6:
SortList(&list);
break;
case 7:
printf("請輸入要插入的資料:> ");
scanf("%d",&x);
printf("請輸入要插入的位置:> ");
scanf("%d",&pos);
InsertBPos(&list, pos, x);
break;
case 8:
SortList(&list);
printf("請輸入要插入的資料:> ");
scanf("%d",&x);
InsertBVal(&list, x);
break;
case 9:
printf("請輸入位置:> ");
scanf("%d",&pos);
DelByPos(&list, pos);
break;
case 10:
printf("請輸入要刪除的元素:> ");
scanf("%d",&x);
DelByValue(&list, x);
break;
case 11:
printf("請輸入要查詢的資料:> ");
scanf("%d", &x);
FindElem(&list, x);
break;
case 12:
ListLength(&list);
break;
case 13:
CleanList(&list);
break;
case 14:
ReverseShow(&list);
break;
case 15:
DestroyList(&list);
break;
}
}
}