線性表順序實現(C語言)

//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;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章