浙江中医药大学-《数据结构》(C语言版)-栈、队列、串、数组

ZCMU-Data Structure (C language)
Part 1 Stack and Queue
1、栈和队列也是线性表,特殊性在于栈和队列的基本操作是线性表操作的子集,是操作受限的线性表。
2、栈是限定仅在表尾(栈顶)进行插入或者删除操作的线性表,它是先进后出(后进先出)的线性表。
3、队列是一种先进先出的线性表。只允许在队尾进行插入,在队头进行删除。
4、顺序栈的表示与实现
     1)初始化
s.base=new SElemType[MAXSIZE];//为顺序栈动态分配一个最大容量为MAXSIZE的数组空间
if(!s.base) exit(OVERFLOW);//存储分配失败
s.top=s.base;//top初始为base,空栈
s.stacksize=MAXSIZE;//置栈的最大容量为MAXSIZE
return OK;
     2)入栈
if(s.top-s.base==s.stacksize) return ERROR;//栈满
*s.top++=e;
return OK;
     3)出栈
if(s.top==s.base) return ERROR;//栈空
e=*--s.top;//栈顶指针减1,将栈顶元素赋给e
return OK;
     4)取栈顶元素
if(s.top!=s.base)//栈非空
return *(s.top-1);//返回栈顶元素的值,栈顶指针不变
5、链栈的表示与实现
      通常,链栈用单链表表示,由于栈主要的操作是在栈顶进行插入或删除操作,显然链表最好,且没必要向单链表一样附加一个头结点。
      1)初始化
      无需设头结点
s=NULL;
return OK;
     2)入栈
     链栈入栈前不需要判断栈是否满,只需要为入栈元素动态分配一个结点空间。
p=new StackNode;//生成新结点
p->data=e;//将新结点数据域置为e
p->next=s;//将新结点插入栈顶
s=p;//修改栈顶指针为p;
return OK;
     3)出栈
     链栈在出栈前需要判断栈是否为空,但是链栈在出栈后需要释放栈元素的栈顶空间。
if(s==NULL) return ERROR;//栈空
e=s->data;//将栈顶元素赋给e
p=s;//将p临时保存栈顶元素空间,以备释放
s=s->next;//修改栈顶指针
delete p;
return OK:
     4)取栈顶元素
if(S!=NULL)
return s->data; //返回栈顶元素的值,栈顶指针不变
6、循环队列-队列的顺序表示和实现  
      在非空队列中,头指针始终指向队列头元素,尾指针始终指向队列尾元素的下一个位置
      1)循环队列初始化
q.base=new QElemType[MAXSIZE];
if(!q.base) exit(OVERFLOW);
q.front=q.rear=0;//头指针和尾指针为0,队列为空
return OK;
      2)求循环队列的长度
return (q.rear-q.front+MAXSIZE)%MAXSIZE;
      3)入队
if((q.rear+1)%MAXSIZE==q.front)//判断队满
  return ERROR;
q.base[q.rear]=e;//新元素插入队尾
q.rear=(q.rear+1)%MAXSIZE;//队尾指针+1
return OK;
      4)出队
if(q.front==q.rear) return ERROR;//队空
 e=q.base[q.front];//保持队头元素
 q.front=(q.front+1)%MAXSIZE;//队头指针+1
return OK;
      5)取队头元素
if(q.front!=q.rear)//队列非空
  return q.base[q.front];//返回队头元素的值,队头指针不变
7、链队-队列的链式表示和实现
      示意图:

      1)初始化
Q.rear=(QueuePtr)malloc(sizeof(QNode) );
  Q.front = Q.rear;
   if(!Q.front) return(OVERFLOW);   
   Q.front -> next = NULL;   
   return OK;
      2)入队
      链队在入队前不需要判断队是否满,需要为入队元素动态分配一个结点
p = ( QueuePtr )malloc(sizeof(QNode));
   if(!p) return(OVERFLOW);
   p->data = e;   
   p -> next = NULL;       
   Q.rear ->next = p;
   Q.rear = p;
      return OK;
      3)出队
if(Q.front == Q.rear) retrun ERROR;
    p = Q.front -> next;
    e = p->data;
    Q.front->next = p->next;
    if(Q.rear == p) Q.rear = Q.front ;
    free(p);
        return OK;
链队出队操作时还需要考虑当队列最后一个元素被删后,队列尾指针也丢失,因此需要对队尾指针重新赋值(指向头结点)。
      4)取队头元素
if(Q.front!=Q.rear)
  return Q.front->next->data;//队头指针不变
Part 2 String and Array
8、串是一种内容受限的线性表,特殊性在于数据元素是一个字符,串中任意个连续的字符组成的子序列称为子串;只有当两个串的长度相等并且各个对应位置的字符都相等时才相等。在串的基本操作中,通常以“串的整体”作为操作对象。
9、串的模式匹配算法
            例如 T= abcac ; S= ababcabcacbab
    • 第一趟匹配  a b a b c a b c a c b a b   (i=3)
    •        a b c                 (j=3)
    • 第二趟匹配  a b a b c a b c a c b a b   (i=2)
    •           a                (j=1)
    • 第三趟匹配  a b a b c a b c a c b a b   (i=7)
    •            a b c a c          (j=5)
    • 第四趟匹配  a b a b c a b c a c b a b   (i=4)
    •             a              (j=1)
    • 第五趟匹配  a b a b c a b c a c b a b   (i=5)
    •              a             (j=1)
    • 第六趟匹配  a b a b c a b c a c b a b   (i=11)
    •                a b c a c      (j=6) 成功!
9、KMP算法
  • KMP算法的改进在于:
  • 每一趟匹配过程中出现字符比较不等时,不需要回朔i指针
  • 只要利用已经部分匹配结果,调整j指针,即将模式向右滑动尽可能远的一段距离,来个提高算法效率
  • 上例的KMP算法匹配过程示意如下
    • 第一趟匹配  a b a b c a b c a c b a b   (i=3)
    •           a b c                       (j=3)
    • 第二趟匹配  a b a b c a b c a c b a b   (i=3 -> 7)
    •                a b c a c               (j=1 -> 5)
    • 第三趟匹配  a b a b c a b c a c b a b   (i=7 -> 11)
    •                        (a)b c a c         (j=2 -> 6)
  • 显然算法复杂度为O(n+m)
code:
int   Index_KMP(SString S, SString T, int  pos)
{    //  利用模式串T的next函数求T在主串 
  // S中第pos个字符之后第一次出现的位置;否则返回0。
  i = pos;  j = 1;
  while(i<=S[0] && j <= T[0]){
    if(j == 0 || S[i] == T[j]){ ++i; ++j;} // 继续比较后续字符
    else    j = next[j];   // 模式串向后移
  }
  if(j > T[0]) return i-T[0]; // 匹配成功
  else  return 0;  // 匹配不成功
}  // Index_KMP

10、数组是类型相同的数据元素构成的有序集合,其特点是结构中的元素本身是具有某种结构的数据,但属于同一数据类型。由于数组一般不做插入或者删除的操作,采用顺序存储结构最合适。
11、数组计算方法以例题形式给出



12、特殊矩阵的压缩存储(数据结构 严蔚敏 P100-102)


















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值