整理日期:2022-12-08

目录

一、线性表

二.栈和队列

三、数组和广义表

四、树和二叉树

五、图

六、查找算法

七、排序算法


一、线性表

(1)将两个递增的有序链表合并为一个递增的有序链表。要求结果链表仍使用原来两个链表的存储空间,不另外占用其它的存储空间。表中不允许有重复的数据。
[题目分析]
合并后的新表使用头指针Lc指向,pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点,从第一个结点开始进行比较,当两个链表La和Lb均为到达表尾结点时,依次摘取其中较小者重新链接在Lc表的最后。如果两个表中的元素相等,只摘取La表中的元素,删除Lb表中的元素,这样确保合并后表中无重复的元素。当一个表到达表尾结点,为空时,将非空表的剩余元素直接链接在Lc表的最后。
[算法描述]
void MergeList(LinkList &La,LinkList &Lb,LinkList &Lc)
{//合并链表La和Lb,合并后的新表使用头指针Lc指向
  pa=La->next;  pb=Lb->next;    
   //pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点
   Lc=pc=La;  //用La的头结点作为Lc的头结点
   while(pa && pb)
{
if(pa->data<pb->data)
{pc->next=pa;pc=pa;pa=pa->next;}
     //取较小者La中的元素,将pa链接在pc的后面,pa指针后移
     else if(pa->data>pb->data)
 {pc->next=pb; pc=pb; pb=pb->next;}
      //取较小者Lb中的元素,将pb链接在pc的后面,pb指针后移
     else //相等时取La中的元素,删除Lb中的元素
{
pc->next=pa;pc=pa;pa=pa->next;
      q=pb->next;delete pb ;pb =q;
}
     }
 pc->next=pa?pa:pb;    //插入剩余段
     delete Lb;            //释放Lb的头结点
}

(2)将两个非递减的有序链表合并为一个非递增的有序链表。要求结果链表仍使用原来两个链表的存储空间,
不另外占用其它的存储空间。表中允许有重复的数据。
[题目分析]
合并后的新表使用头指针Lc指向,pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点,从第一个结点开始进行比较,当两个链表La和Lb均为到达表尾结点时,依次摘取其中较小者重新链接在Lc表的表头结点之后,如果两个表中的元素相等,只摘取La表中的元素,保留Lb表中的元素。当一个表到达表尾结点,为空时,将非空表的剩余元素依次摘取,链接在Lc表的表头结点之后。
[算法描述]

void MergeList(LinkList& La, LinkList& Lb, LinkList& Lc, ) 
{//合并链表La和Lb,合并后的新表使用头指针Lc指向
  pa=La->next;  pb=Lb->next; 
//pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点
  Lc=pc=La; //用La的头结点作为Lc的头结点 
  Lc->next=NULL;
  while(pa||pb )
{//只要存在一个非空表,用q指向待摘取的元素
    if(!pa)  {q=pb;  pb=pb->next;}
//La表为空,用q指向pb,pb指针后移
    else if(!pb)  {q=pa;  pa=pa->next;} 
//Lb表为空,用q指向pa,pa指针后移
    else if(pa->data<=pb->data)  {q=pa;  pa=pa->next;}
//取较小者(包括相等)La中的元素,用q指向pa,pa指针后移
    else {q=pb;  pb=pb->next;}
//取较小者Lb中的元素,用q指向pb,pb指针后移
     q->next = Lc->next;  Lc->next = q;   
//将q指向的结点插在Lc 表的表头结点之后
    }
    delete Lb;             //释放Lb的头结点
}   
(3)已知两个链表A和B分别表示两个集合,其元素递增排列。请设计算法求出A与B的交集,并存放于A链表中。
[题目分析]
只有同时出现在两集合中的元素才出现在结果表中,合并后的新表使用头指针Lc指向。pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点,从第一个结点开始进行比较,当两个链表La和Lb均为到达表尾结点时,如果两个表中相等的元素时,摘取La表中的元素,删除Lb表中的元素;如果其中一个表中的元素较小时,删除此表中较小的元素,此表的工作指针后移。当链表La和Lb有一个到达表尾结点,为空时,依次删除另一个非空表中的所有元素。
[算法描述]
void Mix(LinkList& La, LinkList& Lb, LinkList& Lc) 
{  pa=La->next;pb=Lb->next; 
pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点
Lc=pc=La; //用La的头结点作为Lc的头结点
while(pa&&pb)
{ if(pa->data==pb->data)∥交集并入结果表中。
   { pc->next=pa;pc=pa;pa=pa->next;
     u=pb;pb=pb->next; delete u;}
  else if(pa->data<pb->data) {u=pa;pa=pa->next; delete u;}
else {u=pb; pb=pb->next; delete u;}
}
while(pa) {u=pa; pa=pa->next; delete u;}∥ 释放结点空间
while(pb) {u=pb; pb=pb->next; delete u;}∥释放结点空间
pc->next=null;∥置链表尾标记。
delete Lb;  //释放Lb的头结点
   }

(4)已知两个链表A和B分别表示两个集合,其元素递增排列。请设计算法求出两个集合A和B
的差集(即仅由在A中出现而不在B中出现的元素所构成的集合),并以同样的形式存储,同时返回该集合的元素个数。
[题目分析]
求两个集合A和B的差集是指在A中删除A和B中共有的元素,即删除链表中的相应结点,所以要保存待删除结点的前驱,使用指针pre指向前驱结点。pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点,从第一个结点开始进行比较,当两个链表La和Lb均为到达表尾结点时,如果La表中的元素小于Lb表中的元素,pre置为La表的工作指针pa删除Lb表中的元素;如果其中一个表中的元素较小时,删除此表中较小的元素,此表的工作指针后移。当链表La和Lb有一个为空时,依次删除另一个非空表中的所有元素。
[算法描述]
void Difference(LinkList& La, LinkList& Lb,int *n)
{∥差集的结果存储于单链表La中,*n是结果集合中元素个数,调用时为0
pa=La->next; pb=Lb->next;      
∥pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点
  pre=La;          ∥pre为La中pa所指结点的前驱结点的指针
  while(pa&&pb)
{if(pa->data<q->data){pre=pa;pa=pa->next;*n++;} 
∥ A链表中当前结点指针后移
else if(pa->data>q->data)q=q->next;     ∥B链表中当前结点指针后移
    else {pre->next=pa->next;      ∥处理A,B中元素值相同的结点,应删除
          u=pa; pa=pa->next; delete u;}   ∥删除结点
}
}

(5)设计算法将一个带头结点的单链表A分解为两个具有相同结构的链表B、C,其中B表的结点为A表中值小于零的结点,而C表的结点为A表中值大于零的结点(链表A中的元素为非零整数,要求B、C表利用A表的结点)。
[题目分析]
B表的头结点使用原来A表的头结点,为C表新申请一个头结点。从A表的第一个结点开始,依次取其每个结点p,判断结点p的值是否小于0,利用前插法,将小于0的结点插入B表,大于等于0的结点插入C表。
[算法描述]
void DisCompose(LinkedList A)
{      B=A;
B->next= NULL;    ∥B表初始化
     C=new LNode;∥为C申请结点空间
     C->next=NULL;     ∥C初始化为空表
     p=A->next;        ∥p为工作指针
     while(p!= NULL)
     { r=p->next;      ∥暂存p的后继
       if(p->data<0)
        {p->next=B->next; B->next=p; }∥将小于0的结点链入B表,前插法
       else {p->next=C->next; C->next=p; }∥将大于等于0的结点链入C表,前插法
       p=r;∥p指向新的待处理结点。
     }
}

(6)设计一个算法,通过一趟遍历在单链表中确定值最大的结点。
[题目分析]
假定第一个结点中数据具有最大值,依次与下一个元素比较,若其小于下一个元素,则设其下一个元素为最大值,反复进行比较,直到遍历完该链表。
[算法描述]

ElemType Max (LinkList L ){
    if(L->next==NULL) return NULL;
    pmax=L->next; //假定第一个结点中数据具有最大值
    p=L->next->next;
    while(p != NULL ){//如果下一个结点存在
        if(p->data > pmax->data) pmax=p;//如果p的值大于pmax的值,则重新赋值
        p=p->next;//遍历链表
    }
    return pmax->data;

(7)设计一个算法,通过遍历一趟,将链表中所有结点的链接方向逆转,仍利用原表的存储空间。
[题目分析]
从首元结点开始,逐个地把链表L的当前结点p插入新的链表头部。
[算法描述]
void  inverse(LinkList &L) 
{// 逆置带头结点的单链表 L
    p=L->next;  L->next=NULL;
    while ( p) {
        q=p->next;    // q指向*p的后继
        p->next=L->next;
        L->next=p;       // *p插入在头结点之后
        p = q;
    }
}

(8)设计一个算法,删除递增有序链表中值大于mink且小于maxk的所有元素(mink和maxk是给定的两个参数,其值可以和表中的元素相同,也可以不同
)。
[题目分析]
分别查找第一个值>mink的结点和第一个值 ≥maxk的结点,再修改指针,删除值大于mink且小于maxk的所有元素。
[算法描述]
void delete(LinkList &L, int mink, int maxk) {
   p=L->next; //首元结点
   while (p && p->data<=mink)
      { pre=p;  p=p->next; } //查找第一个值>mink的结点
   if (p) 
{while (p && p->data<maxk)  p=p->next;
                      // 查找第一个值 ≥maxk的结点
      q=pre->next;   pre->next=p;  // 修改指针
      while (q!=p) 
         { s=q->next;  delete q;  q=s; } // 释放结点空间
   }//if
}

(9)已知p指向双向循环链表中的一个结点,其结点结构为data、prior、next三个域,写出算法change§,交换p所指向的结点和它的前缀结点的顺序。
[题目分析]
知道双向循环链表中的一个结点,与前驱交换涉及到四个结点(p结点,前驱结点,前驱的前驱结点,后继结点)六条链。
[算法描述]

void  Exchange(LinkedList p)
∥p是双向循环链表中的一个结点,本算法将p所指结点与其前驱结点交换。
{q=p->llink;
 q->llink->rlink=p;   ∥p的前驱的前驱之后继为p
 p->llink=q->llink;   ∥p的前驱指向其前驱的前驱。
 q->rlink=p->rlink;   ∥p的前驱的后继为p的后继。
 q->llink=p;          ∥p与其前驱交换
 p->rlink->llink=q;   ∥p的后继的前驱指向原p的前驱
 p->rlink=q;          ∥p的后继指向其原来的前驱
}∥算法exchange结束。

(10)已知长度为n的线性表A采用顺序存储结构,请写一时间复杂度为O(n)、空间复杂度为O(1)的算法,该算法删除线性表中所有值为item的数据元素。
[题目分析]
在顺序存储的线性表上删除元素,通常要涉及到一系列元素的移动(删第i个元素,第i+1至第n个元素要依次前移)。本题要求删除线性表中所有值为item的数据元素,并未要求元素间的相对位置不变。因此可以考虑设头尾两个指针(i=1,j=n),从两端向中间移动,凡遇到值item的数据元素时,直接将右端元素左移至值为item的数据元素位置。
[算法描述]
void  Delete(ElemType A[ ],int  n)
∥A是有n个元素的一维数组,本算法删除A中所有值为item的元素。
{i=1;j=n;∥设置数组低、高端指针(下标)。
 while(i<j)
   {while(i<j && A[i]!=item)i++;         ∥若值不为item,左移指针。
    if(i<j)while(i<j && A[j]==item)j--;∥若右端元素为item,指针左移
if(i<j)A[i++]=A[j--];}

二.栈和队列

(1)将编号为0和1的两个栈存放于一个数组空间V[m]中,栈底分别处于数组的两端。当第0号栈的栈顶指针top[0]等于-1时该栈为空,当第1号栈的栈顶指针top[1]等于m时该栈为空。两个栈均从两端向中间增长。试编写双栈初始化,判断栈空、栈满、进栈和出栈等算法的函数。双栈数据结构的定义如下:
Typedef struct
{int top[2],bot[2]; //栈顶和栈底指针
SElemType *V; //栈数组
int m; //栈最大可容纳元素个数
}DblStack
[题目分析]
两栈共享向量空间,将两栈栈底设在向量两端,初始时,左栈顶指针为-1,右栈顶为m。两栈顶指针相邻时为栈满。两栈顶相向、迎面增长,栈顶指针指向栈顶元素。
[算法描述]
(1) 栈初始化
int Init()
{S.top[0]=-1;
S.top[1]=m;
return 1; //初始化成功
}
(2) 入栈操作:
int push(stk S ,int i,int x)
∥i为栈号,i=0表示左栈,i=1为右栈,x是入栈元素。入栈成功返回1,失败返回0
{if(i<0||i>1){ cout<<“栈号输入不对”<<endl;exit(0);}
if(S.top[1]-S.top[0]1) {cout<<“栈已满”<<endl;return(0);}
switch(i)
{case 0: S.V[++S.top[0]]=x; return(1); break;
case 1: S.V[–S.top[1]]=x; return(1);
}
}∥push
(3) 退栈操作
ElemType pop(stk S,int i)
∥退栈。i代表栈号,i=0时为左栈,i=1时为右栈。退栈成功时返回退栈元素
∥否则返回-1
{if(i<0 || i>1){cout<<“栈号输入错误”<<endl;exit(0);}
switch(i)
{case 0: if(S.top[0]-1) {cout<<“栈空”<<endl;return(-1);}
else return(S.V[S.top[0]–]);
case 1: if(S.top[1]m { cout<<“栈空”<<endl; return(-1);}
else return(S.V[S.top[1]++]);
}∥switch
}∥算法结束
(4) 判断栈空
int Empty();
{return (S.top[0]-1 && S.top[1]==m);
}
[算法讨论]
请注意算法中两栈入栈和退栈时的栈顶指针的计算。左栈是通常意义下的栈,而右栈入栈操作时,其栈顶指针左移(减1),退栈时,栈顶指针右移(加1)。

(2)回文是指正读反读均相同的字符序列,如“abba”和“abdba”均是回文,但“good”不是回文。试写一个算法判定给定的字符向量是否为回文。(提示:将一半字符入栈)
[题目分析]
将字符串前一半入栈,然后,栈中元素和字符串后一半进行比较。即将第一个出栈元素和后一半串中第一个字符比较,若相等,则再出栈一个元素与后一个字符比较,……,直至栈空,结论为字符序列是回文。在出栈元素与串中字符比较不等时,结论字符序列不是回文。
[算法描述]
#define StackSize 100 //假定预分配的栈空间最多为100个元素
typedef char DataType;//假定栈元素的数据类型为字符
typedef struct
{DataType data[StackSize];
int top;
}SeqStack;

int IsHuiwen( char *t)
{//判断t字符向量是否为回文,若是,返回1,否则返回0
SeqStack s;
int i , len;
char temp;
InitStack( &s);
len=strlen(t); //求向量长度
for ( i=0; i<len/2; i++)//将一半字符入栈
Push( &s, t[i]);
while( !EmptyStack( &s))
{// 每弹出一个字符与相应字符比较
temp=Pop (&s);
if( temp!=S[i]) return 0 ;// 不等则返回0
else i++;
}
return 1 ; // 比较完毕均相等则返回 1
}

(3)设从键盘输入一整数的序列:a1, a2, a3,…,an,试编写算法实现:用栈结构存储输入的整数,当ai≠-1时,将ai进栈;当ai=-1时,输出栈顶整数并出栈。算法应对异常情况(入栈满等)给出相应的信息。
[算法描述]
#define maxsize 栈空间容量
void InOutS(int s[maxsize])
//s是元素为整数的栈,本算法进行入栈和退栈操作。
{int top=0; //top为栈顶指针,定义top=0时为栈空。
for(i=1; i<=n; i++) //n个整数序列作处理。
{cin>>x); //从键盘读入整数序列。
if(x!=-1) // 读入的整数不等于-1时入栈。
{if(topmaxsize-1){cout<<“栈满”<<endl;exit(0);}
else s[++top]=x; //x入栈。

else //读入的整数等于-1时退栈。
{if(top0){ cout<<“栈空”<<endl;exit(0);}
else cout<<“出栈元素是”<< s[top–]<<endl;}
}
}//算法结束。

(4)从键盘上输入一个后缀表达式,试编写算法计算表达式的值。规定:逆波兰表达式的长度不超过一行,以 符 作 为 输 入 结 束 , 操 作 数 之 间 用 空 格 分 隔 , 操 作 符 只 可 能 有 + 、 − 、 ∗ 、 / 四 种 运 算 。 例 如 : 23434 + 2 ∗ 符作为输入结束,操作数之间用空格分隔,操作符只可能有+、-、*、/四种运算。例如:234 34+2* 符作为输入结束,操作数之间用空格分隔,操作符只可能有+、−、∗、/四种运算。例如:23434+2∗。
[题目分析]
逆波兰表达式(即后缀表达式)求值规则如下:设立运算数栈OPND,对表达式从左到右扫描(读入),当表达式中扫描到数时,压入OPND栈。当扫描到运算符时,从OPND退出两个数,进行相应运算,结果再压入OPND栈。这个过程一直进行到读出表达式结束符 , 这 时 O P N D 栈 中 只 有 一 个 数 , 就 是 结 果 。 [ 算 法 描 述 ] f l o a t e x p r ( ) / / 从 键 盘 输 入 逆 波 兰 表 达 式 , 以 ‘ ,这时OPND栈中只有一个数,就是结果。 [算法描述] float expr( ) //从键盘输入逆波兰表达式,以‘ ,这时OPND栈中只有一个数,就是结果。[算法描述]floatexpr()//从键盘输入逆波兰表达式,以‘’表示输入结束,本算法求逆波兰式表达式的值。
{float OPND[30]; // OPND是操作数栈。
init(OPND); //两栈初始化。
float num=0.0; //数字初始化。
cin>>x;//x是字符型变量。
while(x!=’KaTeX parse error: Expected '}', got '&' at position 51: …: while((x>=’0’&̲&x<=’9’)||x==’.…’)
cout<<“后缀表达式的值为”<<pop(OPND);
}//算法结束。

[算法讨论]假设输入的后缀表达式是正确的,未作错误检查。算法中拼数部分是核心。若遇到大于等于‘0’且小于等于‘9’的字符,认为是数。这种字符的序号减去字符‘0’的序号得出数。对于整数,每读入一个数字字符,前面得到的部分数要乘上10再加新读入的数得到新的部分数。当读到小数点,认为数的整数部分已完,要接着处理小数部分。小数部分的数要除以10(或10的幂数)变成十分位,百分位,千分位数等等,与前面部分数相加。在拼数过程中,若遇非数字字符,表示数已拼完,将数压入栈中,并且将变量num恢复为0,准备下一个数。这时对新读入的字符进入‘+’、‘-’、‘*’、‘/’及空格的判断,因此在结束处理数字字符的case后,不能加入break语句。

(5)假设以I和O分别表示入栈和出栈操作。栈的初态和终态均为空,入栈和出栈的操作序列可表示为仅由I和O组成的序列,称可以操作的序列为合法序列,否则称为非法序列。
①下面所示的序列中哪些是合法的?
A. IOIIOIOO B. IOOIOIIO C. IIIOIOIO D. IIIOOIOO
②通过对①的分析,写出一个算法,判定所给的操作序列是否合法。若合法,返回true,否则返回false(假定被判定的操作序列已存入一维数组中)。
答案:
①A和D是合法序列,B和C 是非法序列。
②设被判定的操作序列已存入一维数组A中。
int Judge(char A[])
//判断字符数组A中的输入输出序列是否是合法序列。如是,返回true,否则返回false。
{i=0; //i为下标。
j=k=0; //j和k分别为I和字母O的的个数。
while(A[i]!=‘\0’) //当未到字符数组尾就作。
{switch(A[i])
{case‘I’: j++; break; //入栈次数增1。
case‘O’: k++; if(k>j){cout<<“序列非法”<<ednl;exit(0);}
}
i++; //不论A[i]是‘I’或‘O’,指针i均后移。}
if(j!=k) {cout<<“序列非法”<<endl;return(false);}
else { cout<<“序列合法”<<endl;return(true);}
}//算法结束。
[算法讨论]在入栈出栈序列(即由‘I’和‘O’组成的字符串)的任一位置,入栈次数(‘I’的个数)都必须大于等于出栈次数(即‘O’的个数),否则视作非法序列,立即给出信息,退出算法。整个序列(即读到字符数组中字符串的结束标记‘\0’),入栈次数必须等于出栈次数(题目中要求栈的初态和终态都为空),否则视为非法序列。

(6)假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾元素站点(注意不设头指针) ,试编写相应的置空队、判队空 、入队和出队等算法。
[题目分析]
置空队就是建立一个头节点,并把头尾指针都指向头节点,头节点是不存放数据的;判队空就是当头指针等于尾指针时,队空;入队时,将新的节点插入到链队列的尾部,同时将尾指针指向这个节点;出队时,删除的是队头节点,要注意队列的长度大于1还是等于1的情况,这个时候要注意尾指针的修改,如果等于1,则要删除尾指针指向的节点。
[算法描述]
//先定义链队结构:
typedef struct queuenode
{Datatype data;
struct queuenode *next;
}QueueNode; //以上是结点类型的定义
typedef struct
{queuenode *rear;
}LinkQueue; //只设一个指向队尾元素的指针

(1) 置空队
void InitQueue( LinkQueue *Q)
{ //置空队:就是使头结点成为队尾元素
 QueueNode *s;
Q->rear = Q->rear->next;//将队尾指针指向头结点
while (Q->rear!=Q->rear->next)//当队列非空,将队中元素逐个出队
{s=Q->rear->next;
Q->rear->next=s->next;
delete s;
 }//回收结点空间
}

(2) 判队空
int EmptyQueue( LinkQueue *Q)
{ //判队空。当头结点的next指针指向自己时为空队
 return Q->rear->next->next==Q->rear->next;
}

(3) 入队
void EnQueue( LinkQueue *Q, Datatype x)
{ //入队。也就是在尾结点处插入元素
QueueNode *p=new QueueNode;//申请新结点
p->data=x; p->next=Q->rear->next;//初始化新结点并链入
Q-rear->next=p;
Q->rear=p;//将尾指针移至新结点
}

(4) 出队
Datatype DeQueue( LinkQueue *Q)
{//出队,把头结点之后的元素摘下
Datatype t;
QueueNode *p;
if(EmptyQueue( Q ))
Error(“Queue underflow”);
p=Q->rear->next->next; //p指向将要摘下的结点
x=p->data; //保存结点中数据
if (p==Q->rear)
{//当队列中只有一个结点时,p结点出队后,要将队尾指针指向头结点
 Q->rear = Q->rear->next;
Q->rear->next=p->next;
}
else
Q->rear->next->next=p->next;//摘下结点p
delete p;//释放被删结点
return x;
}

(7)假设以数组Q[m]存放循环队列中的元素, 同时设置一个标志tag,以tag == 0和tag == 1来区别在队头指针(front)和队尾指针(rear)相等时,队列状态为“空”还是“满”。试编写与此结构相应的插入(enqueue)和删除(dlqueue)算法。
[算法描述]
(1)初始化
SeQueue QueueInit(SeQueue Q)
{//初始化队列
Q.front=Q.rear=0; Q.tag=0;
return Q;
}
(2)入队
SeQueue QueueIn(SeQueue Q,int e)
{//入队列
if((Q.tag1) && (Q.rearQ.front)) cout<<“队列已满”<<endl;
else
{Q.rear=(Q.rear+1) % m;
Q.data[Q.rear]=e;
if(Q.tag0) Q.tag=1; //队列已不空
}
return Q;
}
(3)出队
ElemType QueueOut(SeQueue Q)
{//出队列
if(Q.tag0) { cout<<“队列为空”<<endl; exit(0);}
else
{Q.front=(Q.front+1) % m;
e=Q.data[Q.front];
if(Q.front==Q.rear) Q.tag=0; //空队列
}
return(e);
}

(8)如果允许在循环队列的两端都可以进行插入和删除操作。要求:
① 写出循环队列的类型定义;
② 写出“从队尾删除”和“从队头插入”的算法。
[题目分析] 用一维数组 v[0…M-1]实现循环队列,其中M是队列长度。设队头指针 front和队尾指针rear,约定front指向队头元素的前一位置,rear指向队尾元素。定义front=rear时为队空,(rear+1)%m=front 为队满。约定队头端入队向下标小的方向发展,队尾端入队向下标大的方向发展。
[算法描述]

#define M 队列可能达到的最大长度
typedef struct
{elemtp data[M];
int front,rear;
}cycqueue;

elemtp delqueue ( cycqueue Q)
//Q是如上定义的循环队列,本算法实现从队尾删除,若删除成功,返回被删除元素,否则给出出错信息。
{if (Q.front==Q.rear) { cout<<“队列空”<<endl; exit(0);}
Q.rear=(Q.rear-1+M)%M; //修改队尾指针。
return(Q.data[(Q.rear+1+M)%M]); //返回出队元素。
}//从队尾删除算法结束

void enqueue (cycqueue Q, elemtp x)
// Q是顺序存储的循环队列,本算法实现“从队头插入”元素x。
{if (Q.rear==(Q.front-1+M)%M) { cout<<“队满”<<endl; exit(0)

数据结构算法设计题 (超详细)相关推荐

  1. c语言数据结构算法设计题,数据结构题集(C语言版)算法设计题答案[].doc

    数据结构题集(C语言版)算法设计题答案[].doc 第一章 绪论 1.16 void print_descending(int x,int y,int z)// 按从大到小顺序输出三个数 { scan ...

  2. 数据结构设计_数据结构算法设计题学起来很困难怎么破

    在数据结构学习时候最难的也是最重要的是算法的学习,很多同学不知道一些算法应该怎么学,也不知道应该掌握到什么程度,往往事倍功半.在此特写此篇文章,介绍一下程序设计题的算法怎么应对. 学习方法推荐: 第一 ...

  3. 算法设计题3.16-栈和队列-第3章-《数据结构习题集》-严蔚敏吴伟民版

    习题集完整源码部分 第3章  栈和队列                                                                                 ...

  4. 算法设计题3.27-栈和队列-第3章-《数据结构习题集》-严蔚敏吴伟民版

    习题集完整源码部分 第3章  栈和队列                                                                                 ...

  5. Verilog流水线CPU设计(超详细)

    上篇:Verilog单周期CPU设计(超详细) 本篇完整工程下载链接,已于19.12.17更新 实验 流水线CPU 一.设计目的与要求 1.1 实验内容 1.2 实验要求 1.3 实验创新 二.课程设 ...

  6. c语言算法设计 pdf下载,数据结构算法设计与实现指导(C语言版).pdf

    3 章 栈--实验三 3.1 实验目的及要求 1.理解特 的线性结构--顺序栈的抽象数据类型的定义,及其在 C 语言环境中的 表示方法. 2 .理解顺序栈的基本操作的算法,及其在C 语言环境中一些主要 ...

  7. 点云处理算法整理(超详细教程)

    点云处理算法整理(超详细教程) 目录 一. 线性回归_最小二乘法.梯度下降法 二. 线性回归_最小二乘法.RANSAC算法 三. 最近点迭代_ICP算法 四. 常见三角网格划分_voronoi图和De ...

  8. 猿人学12题超详细解题思路-入门级js(base64编码)

    前言:服务器为了防止获取他们的数据,可谓是使用各种方法,js逆向可以很方便的解析出来一些加密数据,毕竟道高一尺魔高一丈,今天告诉大家袁人学第12题的解题思路,超详细解题思路. 需求:          ...

  9. 数据结构练习题——图(算法设计题)

    ​ (1)分别以邻接矩阵和邻接表作为存储结构,实现以下图的基本操作: ① 增加一个新顶点v,InsertVex(G, v): ② 删除顶点v及其相关的边,DeleteVex(G, v); ③ 增加一条 ...

最新文章

  1. Redis队列的应用
  2. oracle ohs是什么,怎么更改OHS端口为80
  3. 15天内数据迁移!广东省能源局发布通知,这类数据中心面临停工风险!
  4. 自己动手制作(DIY)一个Mini-Linux系统
  5. 前端网页广告无线翻滚_从小白到web前端工程师进阶之路 从0到1到更深
  6. 转 最小生成树(kruskal 算法 和prim算法)
  7. 高通骁龙855刚捂热 骁龙865就现身:三星代工 7nm EUV制程
  8. 提交失败重连java_RxJava出错重连
  9. hcia第五天 结课
  10. Veritas Backup Exec 21配置存储
  11. 关于DllRegisterServer的调用失败的问题解决办法
  12. stm单片机的后缀含义
  13. php目录结构 modules,目录结构
  14. 我的HTC G16 CHACHA A810e版手机如何解锁和一键root的
  15. 微信小程序应用百度地图API
  16. Navicat连接不上远程服务器MySQL提示10038
  17. 推荐10个国外的开源免费的.NET CMS系统
  18. JVM - 进入Java虚拟机的真实世界
  19. 用好“亲和图”带你拨开云雾见月明
  20. 基于机器学习的自适应超体素分割揭示了人脑中的躯体定位组织

热门文章

  1. 键盘只能按一次解决方案
  2. vue教程——13 Vuex
  3. Kubernetes 学习总结(21)—— 深入理解 Kubernetes 中的 DeamonSet
  4. AAAI22参会见闻与论文杂谈
  5. 史上最简单的排序-桶排序
  6. 互联网+不是全民皆商
  7. sql 查询 like '%_1%' 的坑
  8. 4路3G-SDI的两种拼接方式
  9. 华为HCIE专家认证相关简介
  10. (筆記) 使役動詞 (English)