zoukankan      html  css  js  c++  java
  • 数据结构导论 五 栈、队列和数组

     栈

    栈的定义:只是在表的一端进行插入和删除的线性表

    其中:允许插入及删除一端(表尾)称为栈顶(top)

               另一端(表头)称为栈底(Bottom)

    当表中没有元素时称为空栈

    S={i1,i2,i3,i4,i5,i6} 此时 i1称为栈底 i6称为栈顶

                      图1

    进栈:在栈顶插入一个元素

    出栈:在栈顶删除一个元素

                           图2

    特点:

    通过图2 可以看出栈中的元素都是依次进入栈里面,第一个进入到栈里的称为栈底,越往上越是栈顶,而出栈的第一个元素则是栈顶。栈是先进后出的原则,栈称为“后进先出线性表LIFO”

    栈的基本运算有哪些???

    1)初始化栈:InitStack(S);

    2)判断栈:EmptyStack(s);

    3)进栈:push (S,x);

    4)出栈:pop(s);

    5)取栈:Gettop(s);

    顺序栈以及常用名词

    栈容量:栈中可以存放的最大元素个数

    栈顶指针top:指示在当前栈顶元素在栈中位置

    栈空:栈中无元素时,表示栈空

    栈满:数组空间已被站满,成栈满

    下溢:当栈空时,再要求出栈运算,称为“下溢”

    上溢:当栈满时,再要求进栈运算,称为“上溢”

    栈的运算:

    初始化:

    1 int Inistack(Seqstk *stk){
    2 
    3 stk->top=0;
    4 
    5 return 1;
    6 
    7 }

    判断栈:

    1 int EmptyStack(SeqStk *stk){
    2 
    3 if(stl->top==0)retrun 1;
    4 
    5 esle reutn 0;}

    进栈:

    int push(seqstk *stk ,DataType x)
    if(stk->top == masize-1)//判断是否上溢
    {error("栈满");return 0;//上溢
    
    }
    else{
    stk->top++;//修改栈顶指针,
    stk->data[sq->top]=x//元素x插入新栈顶中
    return 1;
    }

    出栈:

    int pop(seqstk *stk){
    if(stk->top==0)//判断是否需要下溢
    {error("栈空");return 0;}//下溢
    else{
    stk->toop;return 1;}//修改栈顶指针,指向新栈顶
    }

    取栈顶元素

    1 DataType GetTop(SeqStk *stk)
    2 {
    3 if(EmptyStack(stk))
    4 return NULLData;
    5 else
    6 return stk->data[stk->top];
    7 }

    链栈的定义

    栈的链式存储结构称为链栈,他是运算受限的的单链表,插入和删除操作今现制在表头位置上进行。栈顶指针就是链表的头指针。

     链栈的如何运算呢???

    初始化:

    1 void InitStack(Lkstk *Ls){
    2 Ls=(LKstk*)malloc(sizeof(Lkstk));
    3 Ls->next=null;
    4 }

    判断栈

    1 nt EmptyStack(LkStk *LS)
    2 {
    3 if(LS->next= =NULL) return 1;
    4 else return 0;
    5 }

    进栈

    void Push (LkStk *LS, DataType x)
    { LkStk *temp;
    temp= (LkStk *) malloc (sizeof (LkStk));
    temp->data=x;
    temp->next=LS->next;
    LS->next=temp;
    }

    出栈

     1 int Pop (LkStk *LS)
     2 { LkStk *temp;
     3 if (!EmptyStack (LS))
     4 { temp=LS->next;
     5 LS->next=temp->next;
     6 free(temp);
     7 return 1;
     8 }
     9 else return 0;
    10 }

    取栈顶元素

    DataType GetTop(LkStk *LS)
    {
    if (!EmptyStack(LS))
    return LS->next->data;
    else
    return NULLData;
    }

    队列

    队列也是一种运算受限的的线性表

    队列:是只允许在表的一端进行插入,而在另一端进行阐述的线性表

    如果将栈比作一个口开的公交车(先下后上),那么队列就可以比作两口开的公交(前门进后门出)

    对头:允许删除一端称为对头(front)

    队尾:允许插入的另一端称为队尾(rear)

    队列:Q={a1,a2,a3,a4,a5,a5。。。}

     队列:先进先出FIFO 

     队列的基本运算都有那些???

    • 队列初始化 InitQueue(Q):
      • 设置一个空队列Q
    • 判队列空 EmptyQueue(Q):
      • 若队列Q为空,则返回值为1,否则返回值为0
    • 入队列 EnQueue(Q,x):
    •     将数据元素x从队尾一端插入队列,使其成为队列的新尾元素;
    • 出队列 OutQueue(Q):
      • 删除队列首元素;
    • 取队列首元素GetHead(Q):
      • 返回队列首元素的值。

    初始化:front=rear=0

    进队:rear加1,元素插入尾指针位置

    出队:front加1,去头指针所值位置

    顺序队列:

    上溢条件:sq.rear==maxsize-1(队满)

    下溢条件:sq.rear==sq.front(队列空)

    循环队列

    定义:为队列分配一块存储空间,并将这块存储空间看成头尾相连接的。

    循环队列的实现

    对插入即入队列:队尾指针增1

    sq.rea(sq.rear+1)1%maxsize

    对删除即出队:对头指针增1

    sq.front=(sq.front+1)%maxsize

    循环队列规定:

    下溢条件即队列空:CQ.front==CQ.rear

    上溢条件即队列满:尾指针从后面追上头指针

    (CQ.rear+1)%maxsize==cq.front(尾赶头)

    循环队列的基本运算:

    队列初始化

    1 void InitQueue(CycQue CQ){
    2 CQ.front=0;CQ.rear=0;}

    判断队列

    1 int EmptyQueue(CycQue CQ)
    2 {if (CQ.rear==CQ.front) return 1;
    3 else return 0;}

    入队列

    int EnQueue(CycQue CQ,DataType x)
    {if ((CQ.rear+1)%maxsize==CQ.front)
    {error(“队列满” );return 0;}
    else {CQ.rear=(CQ.rear+1)%maxsize;
    CQ.data[CQ.rear]=x;
    return 1;}
    }

    出队列

    int OutQueue(CycQue CQ)
    {if (EmptyQueue(CQ))
    {error(“队列空” ); return 0; }
    else {CQ.front=(CQ.front+1)%maxsize;
    return 1; }
    }

    取队列首元素

    DataType GetHead(CycQue CQ)
    {
    if (EmptyQueue(CQ))
    return NULLData;
    else
    return CQ.data[(CQ.front+1)%maxsize];
    }

    链队列的基本运算

    队列的初始化

    1 void init Queue(LkQue *LQ){
    2 LkQueNode *temp;
    3 temp=(LkQuenode*)malloc(sizeof(LkQueNode));
    4 LQ->front=temp;
    5 LQ->rear=temp;
    6 (LQ->front)->next=NULL;
    7 }

    判队列空

    1 Int EmptyQueue(LKQue LQ){
    2 if(LQ.rear==LQ.front)return 1;
    3 else return 0;
    4 }

    入队列:

    1 Void EnQueue(LkQue *LQ;DataType x)
    2 {
    3 LkQueNode *temp;
    4 temp=(LkQueNode *)malloc(sizeof(LkQueNode));
    5 temp->data=x;
    6 temp->next=NULL;
    7 (LQ->rear)->next=temp;
    8 LQ->rear=temp;
    9 }

    出队列:

     1 OutQueue(LkQue *LQ)
     2 { LkQueNode *temp;
     3 if (EmptyQueue(LQ))
     4 {error(“队空” ); return 0; }
     5 else {
     6 temp=(LQ->front)->next;
     7 (LQ->front)->next=temp->next;
     8 if (temp->next==NULL) LQ->rear=LQ->front;
     9 free(temp);
    10 return 1;
    11 }
    12 }

    取队列首元素

     1 DataType GetHead (LkQue LQ)
     2 {
     3 LkQueNode *temp;
     4 if (EmptyQueue(LQ))
     5 return NULLData;
     6 else {
     7 temp=LQ.front->next;
     8 return temp->data;
     9 }
    10 }

     数组

    数组可以看成一种特殊的线性表,其特殊在于,表中的数组元素本身也是一种线性表。

    数据的逻辑结构与运算

    数组是线性表的推广,其每个元素由一个值和一组下标组成,其中下标数称为数组的维数。

     二维数组Amn可以看成是m个行向量组成的向量,也可以看成是n个列向量组成的向量

    数组一旦被定义,它的维数和维界就不再改变。因此,除了结构的初始化和销毁之外,数组通常只有两种基本运算:

    读:给定一组下标,读取相应的数据元素;

    写:给定一组下标,修改相应的数据元素;

    寻址公式:

    例如, 二维数组Amn按“行优先顺序”存储在内存中,假设每个元素占用k个存储单元

    元素aij的存储地址应是数组的基地址加上排在aij前面的元素所占用的单元数。因为aij位于第i行、第j列,前面i行一共有i×n个元素,第i行上aij前面又有j个元素,故它前面一共有i×n+j个元素,

    因此, aij的地址计算函数为:LOC(aij)=LOC(a00)+(i*n+j)*k 

     矩阵的压缩存储

    为了节省存储空间,我们可以对这类矩阵进行压缩存储:即为多个相同的非零元素值分配一个存储空间;对零元素不分配空间。

    1.对称矩阵:

    定义:在一个n阶方阵A中,若元素满足下述性质:aij=aji , 0<=i,j<n-1

    则成A为对称矩阵。

     

     物理存储:

    对称矩阵中元素关于主对角线对称,故只要存储矩阵中上三角或下三角中的元素,让每两个对称的元素共享一个存储空间。

    它的公式:i=n(n+1)/2

    下标变换公式

    1)若i>=j,则下三角形中,a[ij]之前的i行(从第0行道第i-1行)一共由1+2+。。。=i(i+1)/2个元素,在第i行上,a[ij]之前由j个元素,

    因此有:k=i*(i+1)/2+j  0<=k<n(n+1)/2-1

    2)若i<j,则a[ij]是在上三角矩阵中,因为aij=aji,所以只要交换上述对应关系中的i和j即可得到

    k=j*(j+1)/2+i    0<=k<n(n+1)/2-1

     I=max(i,j)J=min(i,j),则ki, j的对应关系
    可统一为: k=I*(I-1)/2+J 0≤kn(n+1)/2 -1

     三角矩阵:

    三角矩阵中的重复元素C可共享一个存储空间,其余的元素正好有n(n+1)/2个,因此,三角矩阵可以压缩存储道向量s[0...n(n+1)/2]中,其中c存放在向量的最后一个分量中

    上三角:

     当i<=j时     k=i( 2n-1+1)/2+j-i

    当i>j时        k=n(n+1)/2

    下三角:

    当i>=j时: k=i(i+1)/2+j

    当i<j时:    k=j(j+1)/2+i

  • 相关阅读:
    NYOJ 625 笨蛋的难题(二)
    NYOJ 102 次方求模
    ZJU Least Common Multiple
    ZJUOJ 1073 Round and Round We Go
    NYOJ 709 异形卵
    HDU 1279 验证角谷猜想
    BNUOJ 1015 信息战(一)——加密程序
    HDU 1202 The calculation of GPA
    "蓝桥杯“基础练习:字母图形
    "蓝桥杯“基础练习:数列特征
  • 原文地址:https://www.cnblogs.com/X404/p/12091207.html
Copyright © 2011-2022 走看看