线性表、栈与队列

本文介绍了线性表的基本概念,包括其类型定义和十二种基本操作,如构造、销毁、查找、获取元素等。此外,还讨论了如何使用线性表来实现栈和队列,阐述了栈的后进先出特性以及队列的先进先出原则。
摘要由CSDN通过智能技术生成

线性表、栈与队列

关于线性表的一些基本操作,以及如何利用线性表实现栈和队列

  • 线性表的类型定义
  • 线性表实现栈
  • 线性表实现队列

线性表的类型定义及基本操作

线性表是n个性质相同的数据元素的有限序列。
在复杂的线性表中,一个数据元素可以由若干个数据项组成。其中常把数据元素称为记录,含有大量记录的线性表又称文件。

线性表的十二种基本操作:
(对线性表内部元素有改变时加&符号)
1、InitList(&L)
操作结果:构造一个空的线性表L。

Status InitList(SqList &L)
{
    L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType)); 
     //申请存储空间
    if(!L.elem)
        exit(0);
    L.length=0;//空表的长度为0
    L.list=LIST_INT_SIZE;//初始数据元素存储容量
    return OK;
 }//InitList

2、DestroyList(&L)
初始条件:线性表L已存在
操作结果:销毁线性表L。

Status Destroy(SqList &L)
{
    free(L.elem);
    L.elem=NULL;
    L.length=0;
    L.listsize=0;
    return OK;
}//Destroy

3、ClearList(&L)
初始条件:线性表L已存在。
操作结果:将L重置为空表。

Status ClearList(SqList &L)
{
   L.length=0; //令线性表的长度为零
   return OK;
}

4、ListEmpty(L)
初始条件:线性表L已存在
操作结果:若L为空表,则返回TRUE,否则返回FALSE。

bool ListEmpty(SqList L)
{
    if(L.length == 0)
        return TRUE;
    else
        return FALSE;
}

5、ListLength(L)
初始条件:线性表L已存在。
操作结果:返回L中数据元素个数

int ListLength(SqList L)
{
    return L.length;
 }

6、GetElem(L, i, &e)
初始条件:线性表L已存在,1<=i<=ListLength(L)。
操作结果:用e返回L中第i个数据元素的值

Status GetElem(SqList L,int i, ElemType &e)
{
    e=*(L.elem+i-1);
    return OK;
}

7、LocateElem(L, e, compare())
初始条件:线性表L已存在,compare()是数据元素判定函数
操作结果:返回L中第一个与e满足关系compare()的数据元素的位序。若这样的元素不存在,则返回值为0。

int LocateElem(SqList L,ElemType e,status(*compare)(ElemType,ElemType))
{
    Elem *p=L.elem; 
    int i=1;
    while(i<=L.length&&!compare(*p++,e))//在线性表长度内且未找到第一个满足条件的元素
    {
        if(i<=L.length)
        return i;
        else
        return 0;
    }

8、PriorElem( L, cur_e, &pre_e)
初始条件:线性表L已存在
操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败,pre_e无定义。

Status PriorElem(SqList L,ElemType cur_e,ElemType &pre_e)
{
   int a;
   a=LocateElem(L,cur_e,equal);
   if(!a||a==1){
       cout<<"查找失败"<<endl;
       return error;
   }
   pre_e=*(L.elem+a-2);
   return OK;
 }

9、NextElem(L, cur_e, &next_e)
初始条件:线性表L已存在
操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回他的后继,否则操作失败,next_e无定义。

Status NextElem(SqList L,ElemType cur_e,ElemType &next_e)
{
    int a;
    a=LocateElem(L,cur_e,equal);
    if(!a||a==L.length){
       cout<<"查找失败"<<endl;
       return error;
    }
    next_e=*(L.elem+a);
    return OK;

 }

10、ListInsert(&L, i, e)
初始条件:线性表L已存在,1<=i<=ListLength(L) + 1
操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加一。

Status ListInsert(SqList &L,int i,ElemType e)
{
    ElemType *newbase,*q,*p;
    if(L.length>=L.listsize){ //当前存储空间已满,增加分配
        if(!(newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType))))
            exit(0);//分配存储空间失败
        L.elem=newbase;//新基址
        L.listsize+=LISTINREMENT;//增加存储容量
    }
        q=L.elem+i-1;//q为插入位置
        for(p=L.elem+L.length-1;p>=q;--p) {
         *(p+1)=*p;//给插入位置之后的元素赋值达到之后元素后移一位的效果
        }
        *q=e;//插入e
        ++L.length;
        return OK;
 }

11、ListDelete(&L, i, e)
初始条件:线性表L已存在且非空,1<=i<=ListLength(L)
操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减一

Status ListDelete(SqList &L,int i,ElemType &e)
{
    ElemType *p,*q;
    if(i<1||i>L.length)//i值不合法
    return error;
    p=L.elem+i-1;//p为被删除元素的位置
    e=*p;//被删除元素的值赋给e
    q=L.elem+L.length-1;//表尾元素的位置
    for(++p;p<=q;++p)
    *(p-1)=*p;
    L.length--;
    return OK;
}    

12、ListTraverse(L,visit())
初始条件:线性表L已存在
操作结果:依次对L的每个数据元素调用函数visit()。一旦visit()失败,则操作失败。

Status ListTraverse(SqList L, void(*visit)(ElemType&))
{
    ElemType *p=L.elem;
    int i;
    for(i=1;i<=L.length;i++)
    visit(*p++);
    cout<<endl;
    return OK;
  }

线性表实现栈

栈是限定仅在表尾进行插入或删除操作的线性表。表尾称为栈顶,表头称为栈底。不含元素的空表成为空栈。

//定义节点
typedef struct data{
    int value;
    struct data *next;
}node;

//定义栈
typedef struct _stack {
    node *top;
    node *bottom;
    size_t num;
}stack;

//构建空栈
void init(stack *s)
{
    s->top = NULL;
    s->bottom = NULL;
    s->num = 0;
}

//判断栈内元素
status StackEmpty(stack *s)
{
    if(s->n == 0)
        return 0;
    else
        return 1;
}

//栈顶
int top(stack *s)
{
    if (StackEmpty(s) == 1) {
        return s->top->data;
    } else {
        printf("stack is empty\n");
        return 0;
    }
}

//出栈
void pop(stack *s)
{
    node *tmp;
    if (StackEmpty(s) == 1) {
        tmp = s->top;
        s->top = tmp->next;
        free(tmp);
        s->num--;
        if (StackEmpty(s) == 1) {
            s->bottom = NULL;
        }
    } else {
        printf("stack is empty\n");
    }
}

//入栈
void push(stack *s, int data)
{
    node *pdata = (node *)malloc(sizeof(node));
    pdata->data = data;
    if (StackEmpty(s) == 0) {
        s->top = pdata;
        s->bottom = pdata;
        pdata->next = NULL;
    } else {
        pdata->next = s->top;
        s->top = pdata;
    }
    s->num++;
}

//清空栈
void clear_stack(stack *s)
{
    while (StackEmpty(s) == 1) {
        pop(s);
    }
}

线性表实现队列

和栈相反,队列是一种先进先出的线性表。它只允许在表的一端进行插入,而在另一端删除元素。

//定义节点
typedef struct data{
    int value;
    struct data *next;
}node;

//定义队列
typedef struct _queue{
    node *front;
    node *rear;
    size_t num;
}queue;


//构建空队列
void init(queue *q)
{
    q->top = NULL;
    q->bottom = NULL;
    q->num = 0;
}

//判断栈内元素
status QueueEmpty(queue *q)
{
    if(q->n == 0)
        return 0;
    else
        return 1;
}

//进列
void push(queue *q, int val)
{
    node *pnode = (node*)malloc(sizeof(node));
    pnode->data = val;
    pnode->next = NULL;
    if (q->rear) {
        q->rear->next = pnode;
    } else {
        q->front = pnode;
    }
    q->rear = pnode;
    q->num++;
}

//出列
void pop(queue *q)
{
    if (QueueEmpty(q) == 1) {
        node *pnode = q->front;
        q->front = q->front->next;
        free(pnode);
        q->num--;
        if (QueueEmpty(q) == 0) {
            q->rear = NULL;
        }
    } else {
        printf("error: pop the empty queue");
    }
}

//清空列
void clear_queue(queue *q)
{
    while (QueueEmpty(q) == 1) {
        pop(q);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值