头像

Bear_King




离线:11小时前


最近来访(223)
用户头像
Peter_5
用户头像
wKingYu
用户头像
zhangzhengyan1
用户头像
小猪快跑ya
用户头像
Feelme
用户头像
chenyanminglovecaixuqi
用户头像
aw2002
用户头像
柚恩不加糖
用户头像
zrzzds
用户头像
jeb_
用户头像
最傻的猪
用户头像
不与悲欢
用户头像
胡二摩斯
用户头像
晴时有风
用户头像
克里斯保罗
用户头像
一万小时定律
用户头像
wangyue2017
用户头像
南有浅夏
用户头像
Turing2021
用户头像
ljlhandsome


二叉树的遍历,递归就是函数内部调用是栈的原理,非递归就是模拟栈的原理,只有层次遍历才是模拟队列的原理

#include<stdio.h>
#include<algorithm>
#include<iostream>
#define MAXSIZE 12
using namespace std;

初始化

// 定义二叉树的结构体
typedef struct Node{
    char data;
    struct node *left;
    struct node *right;
}Node, *Tree;

前序遍历

// 递归前序遍历二叉树
void preOrderRec(Tree root){
    if (root != NULL){
        printf(" %c - ", root->data);
        preOrderRec(root->left);
        preOrderRec(root->right);
    }
}

// 非-递归前序遍历二叉树
void preOrderNRec(Tree root){
    Tree stack[MAXSIZE], node;
    int k = -1;

    if (root == NULL)   return;
    else{
        k++;
        // 仿照一个栈
        stack[k] = root; // 将根节点入栈
        while (k > -1){
            //出栈
            node = stack[k --];
            printf(" %c - ", node->data);

            // 先把右子树放进去,栈是先进去后出,所以下面的左子树先出
            if (node->right != NULL)
                stack[++k] = node->right;
            if (node->left != NULL)
                stack[++k] = node->left;
        }
    }
}

中序遍历

// 递归中序遍历二叉树
void inOrderRec(Tree root)
{
    if (root != NULL)
    {
        inOrderRec(root->left);
        printf(" %c - ", root->data);
        inOrderRec(root->right);
    }
}
// 非-递归实现中序遍历二叉树
void inOrderNRec(Tree root)
{
    Tree stack[MAXSIZE], node;
    int top = 0;

    // 判断树是否为空
    if (root == NULL)   return;

    node = root;

    while (node != NULL || top > 0)
    {
        // 将所有的左子树节点入栈
        while (node != NULL)
        {
            stack[++top] = node;
            node = node->left;
        }
        //  如果右节点为空的话,执行下列语句
        node = stack[top--];
        printf(" %c - ", node->data);

        // 扫描右节点
        node = node->right;
    }

}

后续遍历

// 递归后序遍历二叉树
void backOrderRec(Tree root)
{
    if (root != NULL)
    {
        backOrderRec(root->left);
        backOrderRec(root->right);
        printf(" %c - ", root->data);

    }
}

// 非递归后续遍历
void backOrderNRec(Tree root)
{ 
    Node *p = root;
    Node *stack[MAXSIZE];
    int num = 0;
    Node *have_visited = NULL;

    while (NULL != p || num>0)
    {
        while (NULL != p)
        {
            stack[num++] = p;
            p = p->left;
        }
        p = stack[num - 1];
        if (NULL == p->right || have_visited == p->right)
        {
            printf(" %c - ", p->data);
            num --;
            have_visited = p;
            p = NULL;
        }
        else    p = p->right;
    }

}

层次遍历

//层次遍历
void Level_traversal(Tree root)
{ 
    if (root == NULL)   return;

    Tree stack[MAXSIZE], node;
    node = root;
    int front = 0;  // 使用 front, rear模拟队列
    int rear = 0;

    stack[rear++] = node;

    while (front != rear)
    {
        node = stack[front++]; // 模拟队列,先获取front当前元素,然后在指向 front ++ 位元素
        printf(" %c - ", node->data);

        // 左右子树入队列
        if (node->left != NULL)
            stack[rear++] = node->left;

        if (node->right != NULL)
            stack[rear++] = node->right;
    }
}

发现有问题了,及时跟我反应

返回目录:

https://www.acwing.com/file_system/file/content/whole/index/content/5976074/




Bear_King
11天前

循环链队,这个考试考的多,因为循环链队充分结合了链表和队列,所以很多自命题很爱考

#include<iostream>
#include<stdio.h>
using namespace std;

初始化

//定义结构体
typedef struct qNode
{
    int data;
    struct qNode *next;
}qNode,*queue;

typedef struct
{
    queue front;
    queue rear;
}Queue;

//初始化队列
void initQueue(Queue &Q)
{
    Q.front=Q.rear=(queue)malloc(sizeof(qNode));
    Q.front->next=NULL;
    Q.rear->next=NULL;
}

特判

//判断队列是否为空
bool emptyQueue(Queue &Q)
{
    if(Q.front==Q.rear) return false;
    else    return true;
}

入队

//入队列
void inQueue(Queue &Q,int x)
{
    queue p;    
    p=(queue)malloc(sizeof(qNode));
    p->data=x;
    p->next=Q.front;
    Q.rear->next=p;
    Q.rear=p;
}

出队

//出队列(或者直接函数返回x也行,不需要单独保存在x当中)
void outQueue(Queue &Q,int &x){
    queue p;
    p=(queue)malloc(sizeof(qNode));
    p=Q.front->next;
    Q.rear->next=p;
    x=p->data;
    Q.front->next=p->next;
    if(Q.rear==p)   Q.rear=Q.front;
    delete(p);//释放p所指结点空间 
}  

发现有问题了,及时跟我反应

返回目录:

https://www.acwing.com/file_system/file/content/whole/index/content/5976074/




Bear_King
11天前

只要前面队列理解了,懂得顺序存储结构的循环队列的核心在于取模,就好写

#include<iostream>
#include<stdio.h>
#define MaxSize 12
using namespace std;

初始化

//定义结构体
typedef struct 
{
    int data[MaxSize];
    int front, rear;
}Queue, *PQueue;

//初始化
void initQueue(Queue &Q) 
{
    Q.front = Q.rear = 0;
}

特判

//判断是否为空
bool isEmpty(Queue q) 
{
    if (q.front == q.rear)  return true;
    else    return false;
}

//判断是否队满
bool isFull(Queue &q) 
{
    if ((q.rear + 1)%MaxSize == q.front)    return true;
    else    return false;
}

入队

//入队
bool EnQueue(Queue &q, int x) 
{
    if (isFull(q))  return false;//栈满
    else
    {
        q.data[q.rear] = x;
        q.rear = (q.rear + 1)%MaxSize;
        return true;
    }
}

出队

//出队
bool DeQueue(Queue &q, int &x) 
{
    if (isEmpty(q)) return false;//栈空
    else
    {
        x = q.data[q.front];
        q.front = (q.front+1)%MaxSize;
        return true;
    }
}

发现有问题了,及时跟我反应

返回目录:

https://www.acwing.com/file_system/file/content/whole/index/content/5976074/




Bear_King
13天前

链队,考的频率也有,这个是基础,把这个弄懂了,再去搞循环链队

初始化

//定义结构体
typedef struct qNode
{
    int data;
    struct qNode *next;
}qNode,*queue;

typedef struct
{
    queue front;
    queue rear;
}Queue;

//初始化队列
void initQueue(Queue &Q){   
    Q.front=Q.rear=(queue)malloc(sizeof(qNode));
    Q.front->next=NULL;
}

判空

//判断队列是否为空
bool emptyQueue(Queue &Q)
{
    if(Q.front==Q.rear){
        return false;
    }else{
        return true;
    }
}

入队

//入队列
void inQueue(Queue &Q,int data)
{
    queue p;    
    p=(queue)malloc(sizeof(qNode));
    p->data=data;
    p->next=NULL;
    Q.rear->next=p;
    Q.rear=p;
}

出队

//出队列
void outQueue(Queue &Q,int &data)
{
    queue p;
    p=(queue)malloc(sizeof(qNode));
    p=Q.front->next;
    data=p->data;
    Q.front->next=p->next;
    if(Q.rear==p){
        Q.rear=Q.front;
    }
    delete(p);//释放p所指结点空间 
}  

发现有问题了,及时跟我反应

返回目录:

https://www.acwing.com/file_system/file/content/whole/index/content/5976074/




Bear_King
13天前

顺序队列,emmm,跟栈一样简单

初始化

//定义结构体 
typedef struct {
    int data[MaxSize];
    int front, rear;
}Queue, *PQueue;

//初始化
void initQueue(Queue &Q) 
{
    Q.front = Q.rear = 0;
}

判空,判满

//判断是否为空
bool isEmpty(Queue q) 
{
    if (q.front == q.rear)  return true;
    else    return false;
}

//判断是否队满
bool isFull(Queue &q) 
{
    if ((q.rear + 1)%MaxSize == q.front) 
        return true;
    else
        return false;
}

入队

//入队
bool EnQueue(Queue &q, int x) {
    if (isFull(q))  return false;
    else
    {
        q.data[q.rear] = x;
        q.rear = (q.rear + 1)%MaxSize;
        return true;
    }
}

出队

//出队
bool DeQueue(Queue &q, int &x) 
{
    if (isEmpty(q)) return false;
    else
    {
        x = q.data[q.front];
        q.front = (q.front+1)%MaxSize;
        return true;
    }
}

发现有问题了,及时跟我反应

返回目录:

https://www.acwing.com/file_system/file/content/whole/index/content/5976074/




Bear_King
14天前

先学明白链表,链栈就不是问题,这个出的几率比顺序栈大,因为顺序栈太过简单

#include<iostream>
#include<stdio.h>
#include<stdlib.h>

#define MaxSize 10
using namespace std;

初始化

//定义结构体
typedef struct LinkNode 
{
    int data;
    struct LinkNode *next;
}LinkNode, * LinkStack;

//建栈,初始化 
void initStack(LinkStack &s) 
{
    s = (LinkStack)malloc(sizeof(LinkNode));
    s->next = NULL;
}

判断是否为空

//判断栈是否为空(链栈不需要判断是否已满,结点无限制创建) 
bool isEmpty(LinkStack s) 
{
    if (s->next == NULL)
        return true;
    else
        return false;
}

入栈(向栈顶插入元素)

//入栈
void push(LinkStack &s, int x) 
{
    LinkStack p = s;
    LinkStack q = (LinkStack)malloc(sizeof(LinkNode));
    q->next = p->next;
    p->next = q;
    q->data = x;
}

出栈(删除栈顶元素)

//出栈
void pop(LinkStack &s) 
{
    LinkStack p = s->next;
    s->next = p->next;
    p->next = NULL;
    free(p);
}

读取(返回栈顶元素)

//最简单粗暴的是直接返回栈顶元素(常用)
int getTop(LinkStack s)
{
    if (!isEmpty(s))    return s->next->data;
    else    return false;
}

发现有问题了,及时跟我反应

返回目录:

https://www.acwing.com/file_system/file/content/whole/index/content/5976074/




Bear_King
17天前

顺序栈都比较简单,没啥可说的自己看吧,看懂以后再看链栈

#include<iostream>
#include<stdio.h>
#include<stdlib.h>

#define MaxSize 10
using namespace std;

初始化

typedef struct {
    //int *data;//动态建栈的过程,如果这样写的话,下面 initStack要用第一种方式 
    int data[MaxSize];//静态方式常用,直接定义数组长度,初试化过程就超级简单 
    int top;
}SeqStack,* LinkStack;


//动态初始化,适合结构体里面定义的是 int *data;
void initStack(LinkStack &s) 
{
    s = (SeqStack*)malloc(sizeof(SeqStack));
    s->data = (int *)malloc(sizeof(int)*MaxSize);
    s->top = -1;
}

//静态初始化(常用) 
void initStack(LinkStack &s) 
{
    s->top = -1;
}

判断是否为空,是否已满

//判断栈是否为空,这个太简单了,看看就行 
bool isEmpty(LinkStack s) 
{
    if (s->top == -1)   return true;
    else    return false;
}
//判断栈是否已满,这个也太简单了,看看就行 
bool isFull(LinkStack s) 
{
    if (s->top == MaxSize - 1)  return true;
    else    return false;
}

入栈(向栈顶插入元素)

bool push(LinkStack &s, int x)
{
    if (!isFull(s))     //入栈只管满不满 
    {
        s->top ++;
        s->data[s->top] = x;
        return true;
    }
    else
        return false;   //栈满 
}

出栈(删除栈顶元素)

bool pop(LinkStack &s, int &x) {
    if (!isEmpty(s))    //出栈只管空不空 
    {
        x = s->data[s->top --];
        return true;
    }
    else
        return false;   //栈空 
}

读取(返回栈顶元素)

//这种方式是把栈顶元素赋值给x带拿走 
bool getTop(LinkStack s, int &x) 
{
    if (!isEmpty(s)) 
    {
        x = s->data[s->top];
        return true;
    }
    else
        return false;
}
//最简单粗暴的是直接返回栈顶元素(常用)
int getTop(LinkStack s)
{
    if (!isEmpty(s))    return s->data[s->top];
    else    return false;
}

发现有问题了,及时跟我反应

返回目录:

https://www.acwing.com/file_system/file/content/whole/index/content/5976074/




Bear_King
28天前

所有顺序表的集合操作都在下面,当无序的时候,我默认为保持原集合的元素相对位置不变,写的比较啰嗦,没有硬性要求可以直接简单暴力循环去写

#include<stdio.h>

typedef struct{
    int data[100];
    int length;
}SqList;

1.求A与B交集C

//a,b有序(默认升序)
void fun_1_1(SqList& a,SqList& b,SqList& c)
{
    //双指针算法,i指向a,j指向b,k指向c (属于归并排序里面的思想)
    int i = 0,j = 0,k = 0;
    while(i < a.length && j < b.length)
        if(a.data[i] > b.data[j])   j ++;
        else if(a.data[i] < b.data[j])  i ++;
        else    //若相等则更新c和所有指针 
        {
            c.data[k ++] = a.data[i ++];
            j ++;
        }
    //更新线性表c的长度
    c.length = k;
}

//线性表无序 
int hash[100010];//因为无序,所以先用哈希存储
void fun_1_2(SqList& a,SqList& b,SqList& c)
{
    int k = 0;
    for(int i = 0;i < a.length;i ++)    hash[a.data[i]] = 1;
    for(int i = 0;i < b.length;i ++)//
        if(hash[b.data[i]])
            c.data[k ++] = b.data[i];
    c.length = k;
}

2.求A与C并集C

//线性表有序(默认升序)
void fun_2_1(SqList& a,SqList& b,SqList& c)
{
    //两个有序表,归并成一个有序表 (默认升序) 
    int i = 0,j = 0,k = 0;
    while(i < a.length && j < b.length)
        if(a.data[i] < b.data[j])
        {
            c.data[k ++] = a.data[i ++];
            c.data[k ++] = b.data[j ++];
        } 
        else if(a.data[i] > b.data[j])
        {
            c.data[k ++] = b.data[i ++];
            c.data[k ++] = a.data[j ++];
        }
        else//相等的话,只需要放一个 
        {
            c.data[k ++] = a.data[i ++];
            j ++:
        }
    //把剩下的元素放入c 
    while(i < a.length) c.data[k ++] = a.data[i ++];
    while(j < b.length) c.data[k ++] = b.data[j ++];

    c.length = k;
} 

//线性表无序 (这里的写法是保证归并之后的c,不改变ab中的相对元素位置)
int hash[100010];//因为无序,直接合并,然后用哈希存储去重就可以了 
void fun_2_2(SqList& a,SqList& b,SqList& c)
{
    //一边合并,一边放入哈希,来防止出现重复 
    int i = 0,j = 0,k = 0;
    while(i < a.length && j < b.length)
        //两个值不相等,且前面都没有出现过 
        if(a.data[i] != b.data[b])
        {
            if(!hash[a.data[i]])//判断是否重复出现过,防止重复赋值给c 
                c.data[k ++] = a.data[i];
            if(!hash[b.data[j]])//判断是否重复出现过,防止重复赋值给c 
                c.data[k ++] = b.data[j];
            //更新哈希 
            hash[a.data[i]] = 1;
            hash[b.data[i]] = 1;
        }
        else if(!hash[a.data[i]])//两个值相等的话,判断一个哈希即可 
        {
            c.data[k ++] = a.data[i ++];
            j ++;
            //更新哈希 
            hash[a.data[i]] = 1;
            hash[b.data[i]] = 1;
        }
    //把剩下的元素放入c 
    while(i < a.length)
        if(!hash[a.data[i]])
            c.data[k ++] = a.data[i ++];
    while(j < b.length) 
        if(!hash[b.data[i]])
            c.data[k ++] = b.data[j ++];
    //更新线性表c的长度
    c.length = k;
}

3.求A与B差集C

//线性表有序(默认升序)
void fun_3_1(SqList& a,SqList& b,SqList& c)
{
    //双指针算法,这里要差集,所以谁小先放谁,相等就跳过 
    int i = 0,j = 0,k = 0;
    while(i < a.length && j < b.length)
        if(a.data[i] < b.data[j])
            c.data[k ++] = a.data[i ++];
        else if(a.data[i] > b.data[j])
            c.data[k ++] = b.data[j ++];
        else//相等跳过 
        {
            i ++;
            j ++;
        }
    //把剩下的元素放入c 
    while(i < a.length) c.data[k ++] = a.data[i ++];
    while(j < b.length) c.data[k ++] = b.data[j ++];
    //更新线性表c的长度
    c.length = k;
}


//线性表无序(也使用于有序的情况)
int hashA[100010];//因为无序,所以先用哈希存储
int hashB[100010];
void fun_3_2(SqList& a,SqList& b,SqList& c)
{
    //把A和B分别放到两个哈希里面 
    for(int i = 0;i < a.length;i ++)    hashA[a.data[i]] = 1;
    for(int i = 0;i < a.length;i ++)    hashB[a.data[i]] = 1;
    int i = 0,j = 0,k = 0;
    while(i < a.length && j < b.length)
        //因为只要差值,所以只需判断两者都不相同的情况 
        if(a.data[i] != b.data[b])
        {
            if(!hashB[a.data[i]])//判断是否重复出现过,防止重复赋值给c 
                c.data[k ++] = a.data[i];
            if(!hashA[b.data[j]])//判断是否重复出现过,防止重复赋值给c 
                c.data[k ++] = b.data[j];
            //更新哈希 
            hashA[a.data[i]] = 1;
            hashB[b.data[i]] = 1;
        }
    //把剩下的元素放入c 
    while(i < a.length)
        if(!hashB[a.data[i]])
            c.data[k ++] = a.data[i ++];
    while(j < b.length) 
        if(!hashA[b.data[i]])
            c.data[k ++] = b.data[j ++];
    c.length = k;
}

返回目录:

https://www.acwing.com/file_system/file/content/whole/index/content/5976074/




Bear_King
1个月前

学会基础思想,针对不用情况做变型和调整

//#include<cstdio>
//#include<iostream>
//#include<algorithm>
//#include<cstring>
//#define Maxsize 11
//using namespace std;

1.设计一个算法删除线性表x到y的所有元素

算法分析:

①有序的话,先定位再删除;
②无序的话,双指针对原数组更新(类似于练习1的第4个类型题)

注意: 无序的写法,是这一类问题的模板写法,对有序也有同样适用

// 线性表为递增排序的条件下
void fun_1_1(List &L,int x,int y)
{
    //先判断x和y是否合法,以及表是否为空 
    if(x > y || L.len < 0)  return;
    //遍历线性表,分别取出x,y元素对应左右区间边界的元素下标分别交给m,n做记录
    int m, n;
    for(int i = 0;L.data[i] <= x || L.data[i] <= y;i ++)
        if(L.data[i] <= x)  m = i;
        else if(L.data[i] <= y) n = i;
    //因为线性表递增有序,所以直接删除m到n的符合题意区间元素(这里写得简短,但是逻辑很绕仔细品)
    for(i = n + 1;i < L.len;i ++)
        L.data[i - (n - m + 1)] = L.data[i];
    //更新线性表
    L.len -= n - m + 1;
}

// 线性表为无序的条件下
void fun_1_1(List &L,int x,int y)
{
    //先判断x和y的参数是否合法
    if(x < y)   return;
    //双指针算法:i为遍历原线性表,j为更新线性表
    for(int i = 0,j = 0;i < L.len;i ++)
        if(L.data[i] < x && L.data[i] > y)
        {
            L.data[j] = L.data[i];
            j ++;
        }
    //更新线性表
    L.len = j;
}

2.设计一个算法将小于0的整数放在前部分,大于等于0的整数放在后部分

算法分析:双指针算法,i从前往后,j从后往前,按条件交换元素直到相遇为止

void fun_2(List &L){
    int i = 0,j = L.len - 1;
    while(i < j)
    {
        while(L.data[i] < 0)    i ++;
        while(L.data[j] >= 0)   j --;
        if(i < j)//防止,最后完成以后,ij越界交换 
        {
            int t = L.data[i];
            L.data[i] = L.data[j];
            L.data[j] = t;
        }
    }
}

3.设计一个算法删除重复元素

算法分析:

①有序情况,直接用fun_1_2的模板写法,条件改改,处理一下细节即可
②无序情况,先用数组模拟哈希表做记录,然后再用fun_1_2的模板基础上改写一下即可

// 线性表为有序的条件下去重 
void fun_3(List L)
{
    //判断表是否为空or不需要去重 
    if(L.len == 0 || L.len == 1)    return;
    //双指针算法:i为遍历原线性表,j为更新线性表
    //注意:这里最关键的是要先对j++再更新原数组,不然会出现元素丢失 
    for(int i = 0,j = 0;i < L.len;i ++)
        if(L.data[i] != L.data[j])
        {
            j ++;
            L.data[j] = L.data[i];
        }
    //更新线性表
    L.len = j;
}

// 线性表为无序的条件下去重

//放在函数外面做全局变量,系统会自动对数组初始化为全0,哈希表来用下标做元素,空间做记录重复次数 
int hash[100010];
//注意:当然你也可以吧hash定义在函数里面,但是要写memset(hash,sizeof(hash),0)来初始化为0,因为数组在函数里面定义不会自动初始化为0 
void fun_3(List L)
{
    //判断表是否为空or不需要去重 
    if(L.len == 1 || L.len == 0)    return;
    //开一个非常大的数组用下标来做元素值,存在的元素存储空间放1 
    for(int i = 0;i < L.len;i ++)   hash[ L.data[i] ] = 1;
    // 
    for(int i = 0,j = 0;i < L.len;i ++)
        if(hash[L.data[i]])
        {
            //当元素第一次出现的时候,就把哈希表置0,这样就达到了更新原数组去重 
            hash[L.data[i]] = 0;
            L.data[j] = L.data[i];
            j ++;
        }
    //更新线性表
    L.len = j;
}

返回目录:

https://www.acwing.com/file_system/file/content/whole/index/content/5976074/




Bear_King
1个月前

线性表顺序存储结构完整版实现

#include<iostream>
#define OK 10 
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 100
using namespace std;

typedef char DataType;
typedef struct
{
    DataType data[MAXSIZE];/*注意表值与下表值的对应关系*/
    int last;/*data数组中最后一位存储单元的对应下标值*/
}SeqList;

/*建表:建立新表并初始化位空表*/
SeqList* CreateList()
{
    char c;
    SeqList *Lq;
    Lq = new SeqList;
    Lq->last = -1;
    FLAG:
    cout<<"空表已建立完成,请问您是否对它进行赋值操作?"<<endl<<"(是:Y/y,否:N/n)";
    cin>>c;
    if(c == 'Y' || c == 'y')
    {
        int n;
        system("cls");
        cout<<"请输入你想要输入数据的长度:"<<endl;
        cin>>n;
        for(int i = 0;i < n;i ++)
        {
            cout<<"请输入第"<<i+1<<"个数据"<<endl; 
            cin>>Lq->data[i];
            Lq->last ++;
        }
        return Lq;
    }
        else
            if(c == 'N' || c == 'n')
            {
                return Lq;
            }
            else
            {
                cout<<"输入不合法,请再次输入!!"<<endl;
                goto FLAG;
            }

}

/*按位插入:把x插入i位置*/
bool InsertList(SeqList* L,int i,DataType x)/*注意i是表值不是下标值*/ 
{
    int j;
    if(L->last + 1 < i || i < 1)/*检查插入位置的合法性*/
    {
        cout<<"所选插入位置不在范围内!"<<endl; 
        return ERROR;
    }
    if(L->last == MAXSIZE - 1)      /*检查表是否满*/
    {
        cout<<"顺序表已满!"<<endl;
        return ERROR;
    }
    for(j = L->last;j >= i - 1;j --)/*从最后一项到第i项的所有数据依次往后移动一个存储单元*/
    {
        L->data[j+1] = L->data[j]; 
    }
    L->data[i-1] = x;
    L->last ++;
    return OK; 
}

/*按位删除:把i的数据移除*/
bool DeteList(SeqList* L,int i)
{
    int j;
    if(L->last + 1 < i || i < 1)/*检查删除位置的合法性*/
    {
        cout<<"要删除的位置不存在!"<<endl;
        return ERROR; 
    }
    for(j = i;j <= L->last;j ++)/*从第i项开始到最后一项依次往前移动一位*/
    {
        L->data[j-1] = L->data[j];
    }
    L->last --;
    return OK;
}

/*显示表中所有数据*/
bool ShowList(SeqList* L)
{
    int i;
    cout<<"当前表内所有数据如下:"<<endl;
    for(i = 0;i <= L->last;i ++)
    {
        cout<<"第"<<i+1<<"个数据:"; 
        cout<<L->data[i]<<endl;
    }
    return OK;
}

/*按值查找*/
int SearchList(SeqList* L,DataType x)
{
    int i = 0;
    while(i <= L->last && L->data[i] != x)
    {
        i ++;
    }
    if(i > L->last)
    {
        return ERROR;
    }
    else
    {
        return i;
    }

}

/*显示表中数据长度(个数)*/
bool LengthList(SeqList* L)
{
    cout<<"当前表中数据个数位 : "<<L->last+1;
    return OK; 
}

/*退出系统*/
bool Exit()
{
    char c;
    FLAG:
    cout<<"请再次确认是否退出?"<<endl<<"(是:Y/y,否:N/n)"<<endl;
    cin>>c;
    if(c == 'N' || c == 'n')
        return FALSE;
        else
            if(c == 'Y' || c == 'y')
            {
                exit(0);
                cout<<"退出成功!"<<endl<<"欢迎下次使用!"<<endl; 
            }
            else
            {
                goto FLAG;
            }               
}

/*菜单*/
void menu()
{
    SeqList *L;
    int choice;
    while(1)
    {
        cout<<"\t※↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓※"<<endl;
        cout<<"\t→***********线性表子系统************←"<<endl;
        cout<<"\t→* 1-------建立空的线性表          *←"<<endl;
        cout<<"\t→* 2-------往线性表中插入元素      *←"<<endl;
        cout<<"\t→* 3-------对线性表中进行指定删除  *←"<<endl;
        cout<<"\t→* 4-------显示当前内存中的所有数值*←"<<endl;
        cout<<"\t→* 5-------查找线性表中具体元素    *←"<<endl;
        cout<<"\t→* 6-------显示当前线性表的长度    *←"<<endl;
        cout<<"\t→* 7-------退出界面                *←"<<endl;
        cout<<"\t→***********************************←"<<endl;
        cout<<"\t※↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑※"<<endl;
        cout<<endl<<"请输入菜单号<1 ~ 7> : ";
    FLAG:   
        cin>>choice;
        if(choice < 8 && choice > 0)
        switch(choice)
        {
            case 1:
                    L = CreateList();
                    if(L) cout<<"创建完成!"<<endl;
                    else  cout<<"创建失败!"<<endl;      
                break;
            case 2:
                int n;
                char c;
                    cout<<"请输入你想要插入表中的具体位置:"<<endl;
                    cin>>n;
                    cout<<"请输入你想要插入具体位置的具体数据:"<<endl;
                    cin>>c;
                    if(InsertList(L,n,c)) cout<<"插入完成!"<<endl;
                    else                  cout<<"插入失败!"<<endl;  
                break;
            case 3:
                int m;
                    cout<<"请输入你想要删除的具体位置:"<<endl;
                    cin>>m;
                    if(DeteList(L,m))   cout<<"删除完成!"<<endl;
                    else                cout<<"删除失败!"<<endl;
                break;
            case 4:
                    system("cls");
                    if(ShowList(L))     cout<<"显示完成!"<<endl;
                    else                cout<<"显示失败!"<<endl;
                break;
            case 5:
                char d;
                cin>>d;
                    if(SearchList(L,d)) cout<<"查找完成!"<<endl;
                    else                cout<<"查找失败!"<<endl;
                break;
            case 6:
                    if(LengthList(L))   cout<<"显示长度完成!"<<endl;
                    else                cout<<"显示长度失败!"<<endl;
                break;
            case 7:
                    Exit();
                break;
        }
        else
        {
            cout<<"输入指令不合法,请重新输入!!"<<endl;
            goto FLAG; 
        }
    }
}

int main()
{
    menu();
    return 0;
}
/*
    创建线性表:CreateList()
    求线性表的长度:LengthList(L)
    按值查找:SearchList(SeqList* L,Datatype x)       
    插入操作:InList(L,i,x)
    删除操作:DeleList(L,i)
    显示操作:ShowList(L) 
*/