18.12.22
在計算機中用一組地址連續的存儲單元依次存儲線性表的各個數據元素,稱作線性表的順序存儲結構.
順序存儲結構是存儲結構類型中的一種,該結構是把邏輯上相鄰的節點存儲在物理位置上相鄰的存儲單元中,結點之間的邏輯關係由存儲單元的鄰接關係來體現。由此得到的存儲結構爲順序存儲結構,通常順序存儲結構是藉助於計算機程序設計語言(例如c/c++)的數組來描述的。
順序存儲結構的主要優點是節省存儲空間,因爲分配給數據的存儲單元全用存放結點的數據(不考慮c/c++語言中數組需指定大小的情況),結點之間的邏輯關係沒有佔用額外的存儲空間。採用這種方法時,可實現對結點的隨機存取,即每一個結點對應一個序號,由該序號可以直接計算出來結點的存儲地址。但順序存儲方法的主要缺點是不便於修改,對結點的插入、刪除運算時,可能要移動一系列的結點。
優點:隨機存取表中元素。缺點:插入和刪除操作需要移動元素。
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 1024//定義順序表的最大長度
#define TRUE 1
#define FALSE 0
typedef int datatype;////定義int的別名,或#define datatype int
typedef struct
{
datatype elem[MAXSIZE];
int length; //表長
}SeqList; //定義順序表抽象數據類型
void init_List(SeqList *L)//順序表的初始化
{
L->length = 0;
}
void creat_List(SeqList *L)//創建順序表
{
int i;
printf("請輸入順序表長度:\n");
scanf("%d",&L->length);
printf("請輸入順序表元素:\n");
for(i = 0;i < L->length;i++)
{
scanf("%d",&L->elem[i]);
}
}
void clear_List(SeqList *L)//清空順序表
{
L->length = 0;
}
int loc_List(SeqList *L,int local)//順序表的按值查找
{
int i = 0;
if(L->length == 0)//空表
return FALSE;
for(i = 0;i < L->length;i++)
{
if(L->elem[i] == local)//找到local
return i+1;//返回找到local的位置
}
return 0;//遍歷完順序表沒找到
}
int ins_List(SeqList *L,int i,int data)//順序表中第i個位置插入數據
{
int j;//數據次序
printf("在第%d個位置上插入數據%d\n",i,data);
if(L->length == MAXSIZE)//原順序表已滿
{
printf("overflow\n");
return FALSE;//溢出
}
if(i < 1 || i > L->length)//位置不合適及檢查是否爲空表
{
printf("error,please input the right i\n");//有返回值的函數也可以輸出
return FALSE;
}
for(j = L->length;j >= i;j--)//第i-1個位置之後的數據都後移一位
{
L->elem[j] = L->elem[j-1];
}
L->elem[i-1] = data;
L->length++;//表長加一
return TRUE;
}
int del_List(SeqList *L,int i) //順序表中刪除第i個數據
{
int j; //數據次序
printf("刪除第%d個位置上的數據\n");
if(i < 1 || i > L -> length)
return FALSE;
for(j = i;j < L -> length;j++)
{
L -> elem[j-1] = L -> elem[j];//第i個位置之後的數據都前移一個位置
}
L->length--;//表長減一
return TRUE;
}
void print_List(SeqList *L)//輸出順序表
{
int i;
if(L->length == 0)//判斷空表
printf("表爲空\n");
for(i = 0;i < L->length ;++i)
{
printf("%d ",L->elem[i]);
}
printf("\n");
}
void menu(void)//菜單函數
{
printf("\t\t***************順序表的查找、插入、刪除***************\n");//菜單
printf("\t\t|| a. 建立一個順序表 ||\n");//\t的作用是跳格,即跳到下一個“製表位置”(也有說是TAB位置),在我們所用的系統中一個“製表區”佔8列。“下一製表位置”從第9列開始,
printf("\t\t|| b. 順序表中按值查找 ||\n");
printf("\t\t|| c. 在順序表中第i個位置插入一個元素 ||\n");
printf("\t\t|| d. 刪除在順序表中第i個位置的元素 ||\n");
printf("\t\t|| e. 輸出順序表中的所有元素 ||\n");
printf("\t\t|| f. 清空順序表 ||\n");
printf("\t\t|| q. 退出程序 ||\n");
printf("\t\t******************************************************\n");
}
char menu_select(void)//菜單功能選擇函數
{
char cmd;
printf("\n請輸入您選擇功能的序號(a~e):\n");
cmd = getchar();
while((cmd > 'a' && cmd < 'f') || (cmd == 'q'))
return cmd;
}
main() //省略情況,默認爲 int main()
{
SeqList *L;
int i,local,data;
char cmd;
L = (SeqList *)malloc(sizeof(SeqList));//分配動態存儲空間,創建順序表;
menu();
do
{
cmd = 0;//初始化
switch(menu_select())//菜單選擇,調用menu_select函數(printf語句實現,返回字符)
{
case 'a':
printf("\t\t****************建立一個順序表************************\n");
creat_List(L);
getchar();//清除輸入緩衝區的回車符
break;
case 'b':
printf("\t\t****************在順序表中按值查找********************\n");
printf("請輸入需要查找的值:\n");
scanf("%d",&local);
printf("輸出需要查找的值的位置i:\n");
printf("%d\n",loc_List(L,local));
fflush(stdin);//清除標準輸入緩衝區。相當於getchar()清除輸入緩衝區的回車符
break;
case 'c':
printf("\t\t************在順序表中第i個位置插入一個元素***********\n");
printf("請輸入需要插入的位置i和數據:\n");
scanf("%d%d",&i,&data);
ins_List(L,i,data);
getchar();
break;
case 'd':
printf("\t\t************刪除在順序表中第i個位置的元素*************\n");
printf("請輸入需要刪除的位置i:\n");
scanf("%d",&i);
del_List(L,i);
getchar();
break;
case 'e':
printf("\t\t****************輸出順序表中的所有元素****************\n");
printf("輸出順序表所有元素:\n");
print_List(L);
getchar();
break;
case 'f':
printf("\t\t**********************清空順序表**********************\n");
clear_List(L);
getchar();
break;
case 'q':
printf("\t\t***********************謝謝使用***********************\n");
cmd = 'q';
break;
}
}while(cmd != 'q');
}