//SeqList.h
//結構體和函數的聲明/*
作用:順序表的實現(C語言)
日期:2015年4月
*/
#ifndef SEQLIST_H
#define SEQLIST_H
#include<stdio.h>
#include<malloc.h>
#include<assert.h>
#define MAXSIZE 20 //線性表的最大長度
typedef int ElemType; //重命名成員類型
typedef struct SeqList
{
ElemType *base; //線性表的基指針
int length; //線性表實際存儲了多少數據
int size; //線性表的長度(最多能存儲的數據個數)
}SeqList; //結構體類型重命名
bool isfull(SeqList *list);
bool isempty(SeqList *list);
bool Init_SeqList(SeqList *list);
bool push_back(SeqList *list,ElemType x);
bool push_front(SeqList *list,ElemType x);
void show_seqlist(SeqList *list);
bool pop_back(SeqList *list);
bool pop_front(SeqList *list);
bool insert_pos(SeqList *list,int pos,ElemType x);
bool insert_val(SeqList *list,ElemType x);
bool delete_pos(SeqList *list,int pos);
bool delete_val(SeqList *list,ElemType x);
int find(SeqList *list,ElemType x);
ElemType getvalue(SeqList *list,int pos);
bool modify(SeqList *list,int pos,ElemType x);
bool clear(SeqList *list);
bool destroy(SeqList *list);
bool sort(SeqList *list);
bool resver(SeqList *list);
int length(SeqList *list);
ElemType next(SeqList *list,int pos);
ElemType prio(SeqList *list,int pos);
void change(ElemType *a,ElemType *b);
void menu();
#endif
//SeqList.cpp
//函數實現
#include"SeqList.h"
bool Init_SeqList(SeqList *list) //初始化線性表
{
list->base = (int *)malloc(sizeof(int)*MAXSIZE); //動態開闢MAXSIZE個空間
assert(list->base != NULL); //斷言宏 若條件爲真 則繼續往下執行
list->length = 0;
list->size = MAXSIZE;
return true;
}
bool isfull(SeqList *list) //判滿 如果滿了,返回-1
{
return list->length == MAXSIZE;
}
bool isempty(SeqList *list) //如果空,返回-1
{
return list->length == 0;
}
bool push_back(SeqList *list,ElemType x) //從線性表後面把數據x插入
{
if(isfull(list))
return false;
list->base[list->length] = x;
list->length++;
return true;
}
bool push_front(SeqList *list,ElemType x) //從線性表前面把數據x插入
{
if(isfull(list)) //如果滿,則不能再插入
return false;
for(int i = list->length;i>0;i--) //把下標爲1(包括1)以後的依次往後移一位
{
list->base[i] = list->base[i-1];
}
list->base[0] = x; //下標爲0 的位置插入數據x
list->length++; //線性表的長度增加1
return true;
}
void show_seqlist(SeqList *list) //依次顯示線性表的各個元素
{
int i = 0;
while(i<list->length)
{
printf("%d ",list->base[i++]);
}
printf("\n");
}
bool pop_back(SeqList *list) //把線性表最後一個元素刪除
{ //只需要把線性表長度減一,之後雖然最後一個元素的值還在,
list->length--; //但已經不是合法的成員了,顯示函數不能再顯示最後一個元素
return true;
}
bool pop_front(SeqList *list) //把最前面一個元素刪除
{
if(0 == list->length)
return false;
int i = 0;
while(i<list->length-1) //把下標爲1(包括1)之後的元素都往前移一個,[覆蓋各自前面一個]
{
list->base[i] = list->base[i+1];
i++;
}
list->length--; //長度減一,最前面的被刪除
return true;
}
bool insert_pos(SeqList *list,int pos,ElemType x)//在指定位置上插入數據x
{
if(0>pos || list->length<pos) //位序pos如果爲負,或大於線性表實際存儲的數據個數
{ //則位序不合法
printf("wrong pos\n");
return false;
}
for(int i = list->length;i>pos;i--) //把下標爲pos之後的元素依次後移一個
{
list->base[i] = list->base[i-1];
}
list->base[pos] = x; //pos 位置寫入x
list->length++; //長度加1
return true;
}
bool insert_val(SeqList *list,ElemType x)
{ //在線性表元素按升序排列的情況下插入x
if(isfull(list))
return false;
else
{
int order = find(list,x);//數據x應該被插入的位置
if(order>=0) //order>=0 說明找到該位置
{
insert_pos(list,order,x);
return true;
}
list->base[list->length] = x;//沒有找到該位置,則插到線性表後面
}
return true;
}
bool delete_pos(SeqList *list,int pos) //給一個位置,刪除該位置上的數據
{
if(0>pos || list->length<pos)
{
printf("wrong pos");
return false;
}
for(int i = pos;i<list->length-1;i++) //從位置pos 開始,後面的數據依次前移一位[覆蓋]
{
list->base[i] = list->base[i+1];
}
list->length--; //長度減1
return true;
}
bool delete_val(SeqList *list,ElemType x) //刪除指定元素x
{
for(int k = find(list,x);k<list->length-1;k++)
{
list->base[k] = list->base[k+1];//從x的位置pos開始,後面的數據依次前移一位[覆蓋]
}
list->length--;
return true;
}
int find(SeqList *list,ElemType x) //找到特定元素x的位序
{
int i = 0;
for( i = 0;i<list->length;i++)
{
if(x == list->base[i])
break;
}
if(i == list->length) //判斷是不是由於break而使循環結束
{
printf("沒找到%d\n",x);
return -1;
}
return i; //循環被break掉,找到x,返回位序
}
ElemType getvalue(SeqList *list,int pos) //得到指定位置的值
{
if(0==list->length||0>pos||list->length<=pos)
{
printf("wrong pos\n");
return -1;
}
return list->base[pos];
}
bool modify(SeqList *list,int pos,ElemType x) //修改指定位置pos的值爲新值x
{
if(0==list->length||0>pos||list->length<=pos) //條件有一個滿足,說明位序pos 有錯
{
printf("wrong pos\n");
return false;
}
list->base[pos] = x;
return true;
}
bool clear(SeqList *list) //把線性表清空,即把長度置爲0
{
list->length = 0;
return true;
}
bool destroy(SeqList *list) //銷燬線性表,釋放基指針
{
free(list->base);
return true;
}
bool sort(SeqList *list) //把無序的線性表排序(升序)
{
for(int i = 0; i<list->length-1;i++) // 冒泡排序
{
for(int j = 0; j<((list->length)-1-i);j++)
{
if(list->base[j] > list->base[j+1])
change(list->base+j,list->base+j+1);
//線性表基址加上一個數字,等於數組名加方括號再取地址
}
}
return true;
}
bool resver(SeqList *list) //翻轉一個線性表
{
for(int i = 0; i<list->length/2;i++) //首尾元素依次交換
{
change(list->base+i,list->base+list->length-1-i);
}
return true;
}
int length(SeqList *list) //求線性表長度
{
return list->length;
}
ElemType next(SeqList *list,int pos) //得到指定位置的前面一個元素
{
if(list->length == 0 || pos >= list->length-1 )
{
printf("wrong pos\n");
return -1;
}
return list->base[pos+1];
}
ElemType prio(SeqList *list,int pos) // 得到指定位置的後面一個元素
{
if(list->length == 0 || pos == 1)
{
printf("wrong pos\n");
return -1;
}
return list->base[pos-1];
}
void change(ElemType *a,ElemType *b) //交換兩個數據的值(不需要另外開闢空間)
{
*a = *a + *b;
*b = *a - *b;
*a = *a - *b;
}
void menu() //switch(表達式)中提供選項
{
printf("***********************************\n");
printf("* [0] quit_system [1] push_back *\n");
printf("* [2] push_front [3]show_seqlist*\n");
printf("* [4] pop_back [5] pop_front *\n");
printf("* [6] insert_pos [7] insert_val *\n");
printf("* [8] delete_pos [9] delete_val *\n");
printf("* [10] find [11]getvalue *\n");
printf("* [12] modify [13]clear *\n");
printf("* [14] destroy [15]sort *\n");
printf("* [16] resver [17]length *\n");
printf("* [18] next [19]prio *\n");
printf("***********************************\n");
}
//main.cpp
//用於測試線性表及其函數實現
#include"SeqList.h"
int main()
{
SeqList myList; //定義一個線性表
Init_SeqList(&myList); //初始化線性表
int item = 0; // 用來在循環中接收值的變量
int pos = 0;
int chose = 1;
while(chose)
{
menu();
printf("給出想要操作的序號:\n");
scanf("%d",&chose);
switch(chose)
{
case 0:
chose = 0;
break;
case 1:
printf("輸入要尾插的數據[-1結束]:\n");
while(scanf("%d",&item),item!=-1)
{
push_back(&myList,item);
}
break;
case 2:
printf("輸入要頭插的數據:\n");
while(scanf("%d",&item),item!=-1)
{
push_front(&myList,item);
}
break;
case 3:
show_seqlist(&myList);
break;
case 4:
pop_back(&myList);
break;
case 5:
pop_front(&myList);
break;
case 6:
printf("給出要插入的 位序以及數據:\n");
scanf("%d %d",&pos,&item);
insert_pos(&myList,pos,item);
break;
case 7:
printf("給出要插入的數:\n");
scanf("%d",&item);
insert_val(&myList,item);
break;
case 8:
printf("輸入要刪除的數的位序:\n");
scanf("%d",&pos);
delete_pos(&myList,pos);
break;
case 9:
printf("輸入要刪除的數:\n");
scanf("%d",&item);
delete_val(&myList,item);
break;
case 10:
printf("給出要查找的數:\n");
scanf("%d",&item);
printf(" %d 已找到,位序爲 %d ",item,find(&myList,item));
break;
case 11:
printf("給出想要數的位序:\n");
scanf("%d",&pos);
printf("位序爲 [%d] 的數已找到,%d \n",pos,getvalue(&myList,pos));
break;
case 12:
printf("給出想要修改的數的 位序以及新數據: \n");
scanf("%d %d",&pos,&item);
modify(&myList,pos,item);
printf(" 位序爲%d的數已修改 \n",pos);
break;
case 13:
clear(&myList);
break;
case 14:
destroy(&myList);
break;
case 15:
sort(&myList);
break;
case 16:
resver(&myList);
break;
case 17:
printf("順序表的長度爲:%d\n",length(&myList));
break;
case 18:
printf("想要得到某一位序後面的數值:\n");
scanf("%d",&pos);
printf("位序[%d]後面的值爲:%d\n",pos,next(&myList,pos));
break;
case 19:
printf("想要得到某一位序前面的數值:\n");
scanf("%d",&pos);
printf("位序[%d]後面的值爲:%d\n",pos,prio(&myList,pos));
break;
}
}
return 0;
}