线性表顺序实现(C语言)

来源:互联网 发布:迈克尔.凯恩 知乎 编辑:程序博客网 时间:2024/05/15 15:43

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



0 0
原创粉丝点击