#include <stdio.h>
#include <stdlib.h>
 
#define OK 1
#define ERROR 0
 
//#define INITSIZE 5 //线性表存储空间的初始分配量
//#define LISTINCREMENT 1 //线性表存储空间分配增量
 
//实现线性表的顺序存储结构的类型定义
typedef int DataType;//线性表的数据类型,以×××为例
typedef struct
{
    DataType *elem;//存储空间首地址
    int length;//当前数组长度
    int size;//线性表的大小,即线性表当前分配的存储容量
}SqList;
 
//构造一个空的线性表 L,分配成功返回OK,且设置线性表的长度为0,否则返回ERROR
int InitList(SqList *L,int size)
{
    L->elem=(DataType *)malloc(size*sizeof(int));//动态分配内存 //MAXSIZE*sizeof(DataType)
    if(L->elem==NULL)
    {
        return ERROR;
    }
    else
    {
        L->size=size;//初始化时线性表分配的存储容量
        L->length=0;//数组中的元素个数为零
        return OK;
    }
}
 
//判断线性表是否为空
bool ListEmpty(SqList *L)
{
    int i;
    DataType *p_elem=L->elem;
    for(i=0;i<L->size;i++)
    {
        if(L->elem!=NULL)
        {
            L->elem=p_elem;
            return false;
        }
        L->elem++;
    }
    return true;
}
 
//在数组中追加元素
bool AppendElem(SqList *L,int elem)
{
    if(L->length<L->size)
    {
        L->elem[L->length++]=elem;
        return true;
    }
    else
    {
        printf("数组已满 \r\n");
        return false;
    }
}
 
//在线性表中第 i个数据元素之前插入数据元素e,即在第i个位置插入元素e
int ListInsert(SqList *L,int i,DataType e)
{
    /*
    DataType *q=&(L->elem[i-1]);
    DataType *p,*newBase;
    if(i<1 || i>L->length)
        return ERROR;
    if(L->length>=L->size)
    {
        newBase=(DataType *)realloc(L->elem,L->size+LISTINCREMENT*sizeof(DataType));
        if(newBase==NULL)
            return ERROR;
       
        L->elem=newBase;
        L->size+=LISTINCREMENT;
       
    }
   
    for(p=&(L->elem[L->length-1]);p>=q;p--)
            *(p+1)=*p;
    *q=e;//插入 e的值
    L->length++;
    return OK;
    */
   
    DataType *p,*q=&(L->elem[i-1]);
    if(L->length<L->size && (i>=1 && i<=L->length))
    {
        for(p=&(L->elem[L->length-1]);p>=q;p--)
            *(p+1)=*p;
        *q=e;//插入 e的值
        L->length++;
       
        //for(int k=L->length-1;k>=i-1;k--)
            //L->elem[k+1]=L->elem[k];//将每个元素后移一位
        //L->elem[i-1]=e;
        //L->length++;
       
        return OK;
    }
   
    else
    {
        printf("插入失败 !\r\n");
        return ERROR;
    }
   
}
 
//将线性表 L中第i个数据元素删除,并用e返回其值
int ListDelet(SqList * L,int i,DataType * e)
{
    if(L->length==0)
        return ERROR;
    if(i<1 || i>L->length)
        return ERROR;
    DataType *p,*q;
    *e=L->elem[i-1];//保存线性表 L中第i个数据元素的值
    p=&(L->elem[i]);
    q=&(L->elem[L->length]);
    for(;p<q;p++)
        *(p-1)=*p;
    L->length--;
    return OK;
    /*
    int k;
    if(L->length==0)
        return ERROR;
    if(i<1 || i>L->length)
        return ERROR;
   
    *e=(L->elem[i-1]);
 
    if(i<L->length)
    {
        for(k=i;k<L->length;k++)
            L->elem[k-1]=L->elem[k];
    }
    L->length--;
    return OK;
    */
}
 
//修改线性表中第 i个位置元素的值
int ModifyElem(SqList *L,int i,DataType e)
{
    if(L->length==0)
        return ERROR;
    if(i<1 || i>L->length)
        return ERROR;
    if(i<=L->length)
    {
        L->elem[i-1]=e;
    }
    return OK;
}
 
//返回线性表中第 i个元素的值
int GetElem(SqList L,int i)
{
    int k;
    if(i>=0 && i<=L.length)
    {
        for(k=0;k<L.length;k++)
            if(i==k)
                return L.elem[i];
    }
    else
        return ERROR;
   
}
 
//返回顺序表 L中第1个与e相等元素的位序
int LocationElem(SqList L,DataType e)
{
    int i;
    DataType *p=L.elem;
    for(i=0;i<L.length;i++)
    {
        if(*p==e)
        {
            //L.elem=p;
            return i;
        }
        else
            p++;
    }
}
 
//清空线性表
int ClearList(SqList *L)
{
    if(L->elem==NULL)
        return ERROR;
    DataType *p=L->elem;
    for(int i=0;i<L->length;i++)
    {
        *L->elem=NULL;
        L->elem++;
    }
    L->elem=p;
    L->length=0;
    return OK;
}
 
//取得线性表中数组元素的长度
int ListLength(SqList *L)
{
    return L->length;
}
 
//遍历线性表中的每个元素
void ListTraverse(SqList *L)
{
    if(ListEmpty(L))
        printf("Array is empty!\r\n");
    else
    {
        for(int i=0;i<L->length;i++)
            printf("%d\t",L->elem[i]);
    }
}
 
//倒置
void InverseList(SqList * L)
{
    int i=0,j=L->length-1,temp;
    for(;i<j;i++,j--)
    {
        temp=L->elem[i];
        L->elem[i]=L->elem[j];
        L->elem[j]=temp;
    }
}
 
 
//释放 (销毁)线性表L占用的内存空间
int DestroyList(SqList *L)
{
    if(L->elem==NULL)
        return ERROR;
    else
        free(L->elem);
    return OK;
}
 
//按值插入元素
int InsertListByValue(SqList *L,DataType e)
{
    int i,k,*p;
    p=L->elem;
    if(L->length==L->size)
    {
        printf("线性表中的元素已满 !插入错误!\r\n");
        return ERROR;
    }
    //寻找插入位置
    for (i=0;i<L->length;i++)
    {
        if (*p<e)
        {
            p++;
        }
        else
            break;//找到插入位置 ,在i处
    }
    //移动元素
    for(k=L->length;k>=i;k--)
    {
        L->elem[k+1]=L->elem[k];
    }
    L->elem[i]=e;
    L->length++;
    return OK;
}
 
//删除在最小值和最大值之间的所有值 (边找边删除)
int ListDeleteMaxMin(SqList *L,int min,int max)
{
    int i,k;
    //int listValue;
    if (L->length==0)
        return ERROR;
    //if (L.length<=L.size)
    //{
        for (k=0;k<L->length;k++)
        {
            //listValue=GetElem(L,i);
            if(L->elem[k]>min && L->elem[k]<max)
            {
                for(i=k+1;i<L->length;i++)//移动元素是从 i后面一位开始移动的
                    L->elem[i-1]=L->elem[i];//移动元素
 
                L->length--;
                k--;
            }
        }
    //}
    return OK;
}
 
 
 
void main()
{
    int deleteElem,delPosition,flag,operation;
    int insertElem=0,position;
    int getElemPosition,ModifyElemPosition,value;
    int insertValue,minDelete,maxDelete;
    SqList L;
   
   
    do
    {
        printf("\t线性表应用系统 \r\n");
        printf("*************************************\r\n");
        printf("*         1---------初始化           *\r\n");
        printf("*         2---------判断是否为空表  *\r\n");
        printf("*         3---------求表长           *\r\n");
        printf("*         4---------输出表           *\r\n");
        printf("*         5---------插入元素         *\r\n");
        printf("*         6---------删除元素         *\r\n");
        printf("*         7---------查找元素         *\r\n");
        printf("*         8---------修改元素         *\r\n");
        printf("*         9---------清空表           *\r\n");
        printf("*         10--------释放表空间       *\r\n");
        printf("*         11--------退出             *\r\n");
        printf("*         12--------按值插入         *\r\n");
        printf("*         13--------删除最小值和最大值之间的元素 *\r\n");
        printf("*************************************\r\n");
        printf("输入菜单中的数字进行操作线性表 :\r\n");
        scanf("%d",&operation);
        switch(operation)
        {
            case 1:
                flag=InitList(&L,6);
                AppendElem(&L,1);
                AppendElem(&L,5);
                AppendElem(&L,15);
                printf("\r\n");
                if(flag)
                {
                    printf("初始化已完成 !\r\n");
                }
                break;
            case 2:
                if(ListEmpty(&L))
                    printf("List is empty!\r\n");
                else
                    printf("List is not empty!\r\n");
                break;
            case 3:
                printf("线性表的 (数组)长度 %d\r\n",ListLength(&L));
                break;
            case 4:
                printf("线性表中的元素为 :\r\n");
                printf("\r\n");
                ListTraverse(&L);
                break;
            case 5:
                printf("输入插入元素的值 :\t");
                scanf("%d",&insertElem);
                printf("输入插入元素的位置 :\t");
                scanf("%d",&position);
                ListInsert(&L,position,insertElem);//ListInsert(&L,2,6)
                break;
            case 6:
                printf("输入删除元素的位序 :\t");
                scanf("%d",&delPosition);
 
                ListDelet(&L,delPosition,&deleteElem);//ListDelet(&L,2,&deleteElem);
                printf("\r\n删除的元素为 %d\r\n",deleteElem);
                break;
            case 7:
               
                printf("\n取得的元素为 :%d\t\r\n",GetElem(L,getElemPosition));//GetElem(L,2)
                break;
            case 8:
                printf("输入要修改元素的位序 \r\n");
                scanf("%d",&ModifyElemPosition);
                if(ModifyElem(&L,ModifyElemPosition,value))//ModifyElem(&L,2,8)
                    printf("修改成功 !\r\n");
                printf("线性表中的元素为 :\r\n");
                ListTraverse(&L);
                break;
            case 9:
                //ClearList(L);
                if(ClearList(&L))
                    printf("ClearList is OK!\r\n");
                break;
            case 10:
                if(DestroyList(&L))
                    printf("DestroyList is OK!\r\n");
                break;
            case 11:
                return;
            case 12:
                printf("请输入要插入的值 :\t");
                scanf("%d",&insertValue);
                InsertListByValue(&L,insertValue);
                printf("线性表中的元素为 :\r\n");
                ListTraverse(&L);
                break;
            case 13:
                printf("请输入最小值 :\t");
                scanf("%d",&minDelete);
                printf("请输入最大值 :\t");
                scanf("%d",&maxDelete);
                ListDeleteMaxMin(&L,minDelete,maxDelete);
                printf("删除后的元素为 :\r\n");
                printf("\r\n");
                ListTraverse(&L);
                break;
        }
    }while(operation); 
    //return 0;
}