2015广工数据结构anyview题库

来源:互联网 发布:好看的超能力美剧 知乎 编辑:程序博客网 时间:2024/05/14 08:17

/**********

【题目】试写一算法,如果三个整数abc的值

不是依次非递增的,则通过交换,令其为非递增。

***********/

void Descend(int &a, int &b, int &c)

/* 通过交换,令 a >= b >= c */

{   int d;

   if(a<b)

     {

       d=a;

       a=b;b=d;

     }

     if(a<c)

     {

       d=a;

       a=c;c=d;

     }

     if(b<c)

     {

       d=b;

       b=c;c=d;

     }

   

}

 

/**********

【题目】试编写算法求一元多项式

    P(x) = a0 + a1x + a2x^2 + ... + anx^n

的值P(x0),并确定算法中每一语句的执行次数和整个算法

的时间复杂度。

**********/

float Polynomial(int n, int a[], float x)

/* 求一元多项式的值P(x)。                  */

/* 数组a的元素a[i]i次项的系数,i=0,...,n */

{

     int j=1,i=0;

     float c = 1;

     float t = 0;

     while(i<=n){

       while(j<=i){

         c=c*x;

         j++;

       }

       t =t+ (a[i]*c);

       i++;

     }

     return t;    

}

 

/**********

【题目】已知k阶裴波那契序列的定义为

    f(0)=0, f(1)=0, ..., f(k-2)=0, f(k-1)=1;

    f(n)=f(n-1)+f(n-2)+...+f(n-k), n=k,k+1,...

试编写求k阶裴波那契序列的第m项值的函数算法,

km均以值调用的形式在函数参数表中出现。

**********/

Status Fibonacci(int k, int m, int &f)

/* k阶斐波那契序列的第m项的值f */

{   int t[60],sum,i,j;

    if(k<2||m<0) return ERROR;

    if(m<k-1) f=0;

    else if(m==k-1) f=1;

    else

    {

      for(i=0;i<=k-2;i++)

      {t[i]=0;

      t[k-1]=1;

      for(i=k;i<=m;i++)

      {sum=0;

      for(j=i-k;j<i;j++)

      sum+=t[j];

      t[i]=sum;}}

    f=t[m];

    }                                                                                

    return OK;

}

 

/**********

【题目】试编写算法,计算i!×2^i的值并存入数组

a[0..n-1]的第i-1个分量中(i=1,2,,n)。假设计

算机中允许的整数最大值为MAXINT,则当对某个k

(1kn)使k!×2^k>MAXINT时,应按出错处理。注意

选择你认为较好的出错处理方法。

**********/

Status Series(int a[], int n)

/* i!*2^i序列的值并依次存入长度为n的数组a;     */

/* 若所有值均不超过MAXINT,则返回OK,否则OVERFLOW */

{

     int i,sum=0,sum1=1,sum2=1;

     int j;

     for(i=1;i<=n;i++)

     {

        for(j=i;j>0;j--) sum1*=j;

        for( j=i;j>0;j--) sum2=sum2*2;

 

        sum=sum1*sum2;

        if(sum>MAXINT||sum1>MAXINT||sum2>MAXINT)

         {

           

           return OVERFLOW;

           break;

         }

         a[i-1]=sum;

         sum1=1;sum2=1;

     }

     return OK;

}

 

/**********

【题目】假设有ABCDE五个高等院校进行田径对抗赛,

各院校的单项成绩均以存入计算机并构成一张表,表中每一行

的形式为:

        项目名称   性别   校名   成绩   得分

编写算法,处理上述表格,以统计各院校的男、女总分和团体

总分,并输出。

**********/

void Scores(ResultType *result, ScoreType *score)

/* 求各校的男、女总分和团体总分,并依次存入数组score */

/* 假设比赛结果已经储存在result[ ]数组中,            */

/* 并以特殊记录 {"", male, ' ', "", 0 }(域scorce=0*/

/* 表示结束                                          */

{

    typedef enum {female,male} Sex;

typedef struct{

  char *sport;     // 项目名称

  Sex  gender;     // 性别(女:female;男:male

  char schoolname; // 校名为'A','B','C','D''E'

  char *result;    // 成绩

  int score;       // 得分(7,5,4,3,21

} ResultType;

 

typedef struct{

  int malescore;   // 男子总分

  int femalescore; // 女子总分

  int totalscore;  // 男女团体总分

} ScoreType;

 

   int i=0;

 while(result[i].sport!=NULL)  

 {  

 switch(result[i].schoolname)     /*使用switch语句记录各院校的成绩*/

 {  

 case 'A':  

 score[0].totalscore+=result[i].score;  

  

 if(result[i].gender==male)  

 score[0].malescore+=result[i].score;  

 else  

 score[0].femalescore+=result[i].score;  

 break;  

 case 'B':  

 score[1].totalscore+=result[i].score;  

 if(result[i].gender==male)  

 score[1].malescore+=result[i].score;  

 else  

 score[1].femalescore+=result[i].score;  

 break;  

 case 'C':  

 score[2].totalscore+=result[i].score;  

 if(result[i].gender==male)  

 score[2].malescore+=result[i].score;  

 else  

 score[2].femalescore+=result[i].score;  

 break;  

 case 'D':  

 score[3].totalscore+=result[i].score;  

 if(result[i].gender==male)  

 score[3].malescore+=result[i].score;  

 else  

 score[3].femalescore+=result[i].score;  

 break;  

 case 'E':  

 score[4].totalscore+=result[i].score;  

 if(result[i].gender==male)  

 score[4].malescore+=result[i].score;  

 else  

 score[4].femalescore+=result[i].score;  

 break;  

 }  

 i++;  

 }  

 int j;  

 for( j=0;j<5;j++)  

 {  

 printf("the school %s: ", result[i].schoolname) ;   /*输出各院校的男女总分和团体总分*/

 printf("total: %f",&score[i].totalscore);  

 printf("male: %f",&score[i].malescore);  

 printf("female: %f",&score[i].femalescore);  

}  

}

//}

 

/**********

【题目】试写一算法,对序列S的第i个元素赋以值e

序列的类型定义为:

typedef struct {

  ElemType  *elem;

  int  length;

} Sequence;

***********/

Status Assign(Sequence &S, int i, ElemType e)

/* 对序列S的第i个元素赋以值e,并返回OK*/

/* Si不合法,则赋值失败,返回ERROR   */

{

    if(i<0||i>S.length||S.elem==NULL) return ERROR;

    else

    {

      S.elem[i]=e;

    }

    return OK;

}

 

/**********

【题目】试写一算法,由长度为n的一维数组a构建一个序列S

序列的类型定义为:

typedef struct {

  ElemType  *elem;

  int  length;

} Sequence;

***********/

Status CreateSequence(Sequence &S, int n, ElemType *a)

/* 由长度为n的一维数组a构建一个序列S,并返回OK*/

/* 若构建失败,则返回ERROR                       */

{  

   S.elem=(ElemType*)malloc(n*sizeof(ElemType));

   if(S.elem==a||n<=0) return ERROR;

   S.elem = a;

   S.length = n;    

  if(&S.elem[0]==NULL) return ERROR;

    else return OK;

}

 

/**********

【题目】链表的结点和指针类型定义如下

    typedef struct LNode {

       ElemType  data;

       struct LNode *next;

    } LNode, *LinkList;

试写一函数,构建一个值为x的结点。

***********/

LinkList MakeNode(ElemType x)

/* 构建一个值为x的结点,并返回其指针。*/

/* 若构建失败,则返回NULL。           */

{   LNode *p;

    p = (LNode*)malloc(sizeof(LNode));

    if(p)

    {

      p->data=x;

      p->next=NULL;

    }

    else return NULL;

    return p;

 

}

 

/**********

【题目】链表的结点和指针类型定义如下

    typedef struct LNode {

       ElemType  data;

       struct LNode *next;

    } LNode, *LinkList;

试写一函数,构建长度为2且两个结点的值依次为xy的链表。

**********/

LinkList CreateLinkList(ElemType x, ElemType y)

/* 构建其两个结点的值依次为xy的链表。*/

/* 若构建失败,则返回NULL。            */

{

    LNode *p1,*p2;

    p1 = (LNode*)malloc(sizeof(LNode));

    p2 = (LNode*)malloc(sizeof(LNode));    

    if(p1)

    {

      p1->data=x;

      p1->next=p2;

    }else return NULL;

    if(p2)

    {

      p2->data=y;

      p2->next=NULL;

    }

    

    else return NULL;

    return p1;

}

 

/**********

【题目】链表的结点和指针类型定义如下

    typedef struct LNode {

       ElemType  data;

       struct LNode *next;

    } LNode, *LinkList;

试写一函数,构建长度为2的升序链表,两个结点的值

分别为xy,但应小的在前,大的在后。

**********/

LinkList CreateOrdLList(ElemType x, ElemType y)

/* 构建长度为2的升序链表。  */

/* 若构建失败,则返回NULL*/

{

       LNode *p, *q;

     p = (LNode*)malloc(sizeof(LNode));

     q = (LNode*)malloc(sizeof(LNode));

     p->data = x;

     q->data = y;

     if(x>y){    

     q->next = p;

     p->next = NULL;

     return q;

     }else{    

     p->next = q;

     q->next = NULL;

     return p;

     }

}

 

/**********

【题目】试写一算法,实现顺序栈的判空操作

StackEmpty_Sq(SqStack S)

顺序栈的类型定义为:

typedef struct {

  ElemType *elem; // 存储空间的基址

  int top;        // 栈顶元素的下一个位置,简称栈顶位标

  int size;       // 当前分配的存储容量

  int increment;  // 扩容时,增加的存储容量

} SqStack;        // 顺序栈

***********/

Status StackEmpty_Sq(SqStack S)

/* 对顺序栈S判空。                      */

/* S是空栈,则返回TRUE;否则返回FALSE */

{

    if(S.elem==NULL||S.top==NULL) return TRUE;

    else return FALSE;

}

 

/**********

【题目】试写一算法,实现顺序栈的取栈顶元素操作

GetTop_Sq(SqStack S, ElemType &e)

顺序栈的类型定义为:

typedef struct {

  ElemType *elem;  // 存储空间的基址

  int top;         // 栈顶元素的下一个位置,简称栈顶位标

  int size;        // 当前分配的存储容量

  int increment;   // 扩容时,增加的存储容量

} SqStack;         // 顺序栈

***********/

Status GetTop_Sq(SqStack S, ElemType &e)

/* 取顺序栈S的栈顶元素到e,并返回OK*/

/* 若失败,则返回ERROR。              */

{

   if(S.top==0){

      return ERROR;

}  

    e=S.elem[S.top-1];

    return OK;

 

}

 

/**********

【题目】试写一算法,实现顺序栈的出栈操作

Pop_Sq(SqStack &S, ElemType &e)

顺序栈的类型定义为:

typedef struct {

  ElemType *elem;  // 存储空间的基址

  int top;         // 栈顶元素的下一个位置,简称栈顶位标

  int size;        // 当前分配的存储容量

  int increment;   // 扩容时,增加的存储容量

} SqStack;         // 顺序栈

***********/

Status Pop_Sq(SqStack &S, ElemType &e)

/* 顺序栈S的栈顶元素出栈到e,并返回OK*/

/* 若失败,则返回ERROR。               */

{

     if(0==S.top) return ERROR;

    e=S.elem[--S.top];

    return OK;

}

 

/**********

【题目】若顺序栈的类型重新定义如下。试编写算法,

构建初始容量和扩容增量分别为sizeinc的空顺序栈S

typedef struct {

  ElemType *elem; // 存储空间的基址

  ElemType *top;  // 栈顶元素的下一个位置

  int size;       // 当前分配的存储容量

  int increment;  // 扩容时,增加的存储容量

} SqStack2;

***********/

Status InitStack_Sq2(SqStack2 &S, int size, int inc)

/* 构建初始容量和扩容增量分别为sizeinc的空顺序栈S*/

/* 若成功,则返回OK;否则返回ERROR。                 */

{

    S.elem=(ElemType*)malloc(size*sizeof(ElemType));

    if(NULL==S.elem) return OVERFLOW;

    if(size<=0||inc<=0) return ERROR;

    S.top=S.elem;

    S.size=size;

    S.increment=inc;

    return OK;

 

}

 

/**********

【题目】若顺序栈的类型重新定义如下。试编写算法,

实现顺序栈的判空操作。

typedef struct {

  ElemType *elem; // 存储空间的基址

  ElemType *top;  // 栈顶元素的下一个位置

  int size;       // 当前分配的存储容量

  int increment;  // 扩容时,增加的存储容量

} SqStack2;

***********/

Status StackEmpty_Sq2(SqStack2 S)

/* 对顺序栈S判空。                      */

/* S是空栈,则返回TRUE;否则返回FALSE */

{

     if(S.top==S.elem)return TRUE;

    else  return FALSE;

 

}

 

/**********

【题目】若顺序栈的类型重新定义如下。试编写算法,

实现顺序栈的入栈操作。

typedef struct {

  ElemType *elem; // 存储空间的基址

  ElemType *top;  // 栈顶元素的下一个位置

  int size;       // 当前分配的存储容量

  int increment;  // 扩容时,增加的存储容量

} SqStack2;

***********/

Status Push_Sq2(SqStack2 &S, ElemType e)

/* 若顺序栈S是满的,则扩容,若失败则返回ERROR*/

/* e压入S,返回OK。                          */

{

    ElemType *newbase;

    if((S.top-S.elem)>S.size){

       newbase=(ElemType*)realloc(S.elem,(S.size+S.increment)*sizeof(ElemType));

       if(NULL==newbase) return ERROR;

       S.elem=newbase;

       S.size=S.size+S.increment;

    }

     *S.top=e;

    S.top++;

    return OK;

}

 

/**********

【题目】若顺序栈的类型重新定义如下。试编写算法,

实现顺序栈的出栈操作。

typedef struct {

  ElemType *elem; // 存储空间的基址

  ElemType *top;  // 栈顶元素的下一个位置

  int size;       // 当前分配的存储容量

  int increment;  // 扩容时,增加的存储容量

} SqStack2;

***********/

Status Pop_Sq2(SqStack2 &S, ElemType &e)

/* 若顺序栈S是空的,则返回ERROR;    */

/* 否则将S的栈顶元素出栈到e,返回OK*/

{

     if(S.top==S.elem) return ERROR;

    e=*(--S.top);

    return OK;

 

}

 

/**********

【题目】试写一算法,借助辅助栈,复制顺序栈S1得到S2

顺序栈的类型定义为:

typedef struct {

  ElemType *elem; // 存储空间的基址

  int top;        // 栈顶元素的下一个位置,简称栈顶位标

  int size;       // 当前分配的存储容量

  int increment;  // 扩容时,增加的存储容量

} SqStack;        // 顺序栈

可调用顺序栈接口中下列函数:

Status InitStack_Sq(SqStack &S, int size, int inc); // 初始化顺序栈S

Status DestroyStack_Sq(SqStack &S); // 销毁顺序栈S

Status StackEmpty_Sq(SqStack S);    // S判空,若空则返回TRUE,否则FALSE

Status Push_Sq(SqStack &S, ElemType e); // 将元素e压入栈S

Status Pop_Sq(SqStack &S, ElemType &e); // S的栈顶元素出栈到e

***********/

Status CopyStack_Sq(SqStack S1, SqStack &S2)

/* 借助辅助栈,复制顺序栈S1得到S2。    */

/* 若复制成功,则返回TRUE;否则FALSE*/

{

    SqStack S3;   

    ElemType e;

    InitStack_Sq(S3,S1.size,S1.increment);

    InitStack_Sq(S2,S1.size,S1.increment);

    while(StackEmpty_Sq(S1)!=TRUE){

       Pop_Sq(S1,e);

       Push_Sq(S3,e);

       }

    while(StackEmpty_Sq(S3)!=TRUE){

       Pop_Sq(S3,e);

       Push_Sq(S2,e);

     }

 

     return TRUE;

}

 

/**********

【题目】试写一算法,求循环队列的长度。

循环队列的类型定义为:

typedef struct {

  ElemType *base;  // 存储空间的基址

  int front;       // 队头位标

  int rear;        // 队尾位标,指示队尾元素的下一位置

  int maxSize;     // 最大长度

} SqQueue;

***********/

int QueueLength_Sq(SqQueue Q)

/* 返回队列Q中元素个数,即队列的长度。*/

{    return  (Q.rear-Q.front+Q.maxSize)%Q.maxSize;

 

}

 

/**********

【题目】如果希望循环队列中的元素都能得到利用,

则可设置一个标志域tag,并以tag值为01来区分尾

指针和头指针值相同时的队列状态是""还是""

试编写与此结构相应的入队列和出队列的算法。

本题的循环队列CTagQueue的类型定义如下:

typedef struct {

  ElemType elem[MAXQSIZE];

  int tag;

  int front;

  int rear;

} CTagQueue;

**********/

Status EnCQueue(CTagQueue &Q, ElemType x)

/* 将元素x加入队列Q,并返回OK*/

/* 若失败,则返回ERROR。       */

{

     if(Q.tag==1&&Q.front==Q.rear)return ERROR;

   Q.elem[Q.rear]=x;

   Q.rear=(Q.rear+1)%MAXSIZE;

   if(Q.front==Q.rear)

   Q.tag=1;

   return OK;

}

 

Status DeCQueue(CTagQueue &Q, ElemType &x)

/* 将队列Q的队头元素退队到x,并返回OK*/

/* 若失败,则返回ERROR。               */

{ if(Q.tag==0&&Q.front==Q.rear)

       return ERROR;

      x=Q.elem[Q.front];

      Q.front=(Q.front+1)%MAXSIZE;

      if(Q.front==Q.rear)

         Q.tag=0;

      return OK;

 

}

 

/**********

【题目】假设将循环队列定义为:以域变量rear

length分别指示循环队列中队尾元素的位置和内

含元素的个数。试给出此循环队列的队满条件,并

写出相应的入队列和出队列的算法(在出队列的算

法中要返回队头元素)。

本题的循环队列CLenQueue的类型定义如下:

typedef struct {

  ElemType elem[MAXQSIZE];

  int length;

  int rear;

} CLenQueue;

**********/

Status EnCQueue(CLenQueue &Q, ElemType x)

  /* 将元素x加入队列Q,并返回OK*/

  /* 若失败,则返回ERROR。       */

{    if(Q.length==MAXQSIZE) return ERROR;

    Q.length++;   

    Q.rear=(Q.rear+1)%MAXQSIZE;

    Q.elem[Q.rear]=x;

    return TRUE;

 

}

Status DeCQueue(CLenQueue &Q, ElemType &x)

  /* 将队列Q的队头元素退队到x,并返回OK*/

  /* 若失败,则返回ERROR。               */

{

    int front;

    if(Q.length==0) return ERROR;

      Q.length--;

    front=MAXQSIZE-Q.length+Q.rear;

    x=Q.elem[front%MAXQSIZE];

    front=(front+1)%MAXQSIZE;

    return OK;

}

 

/**********

【题目】已知k阶斐波那契序列的定义为:

    f0=0,  f1=0,  ,  fk-2=0,  fk-1=1;

    fn=fn-1+fn-2++fn-k,  n=k,k+1,

试利用循环队列编写求k阶斐波那契序列中第

n+1fn的算法。

 

本题的循环队列的类型定义如下:

typedef struct {

  ElemType *base; // 存储空间的基址

  int front;      // 队头位标

  int rear;       // 队尾位标,指示队尾元素的下一位置

  int maxSize;    // 最大长度

} SqQueue;

**********/

long Fib(int k, int n)

/* k阶斐波那契序列的第n+1fn */

{

    int i,j ;

   if(1 >=k|| 0 > n) return ERROR;

   SqQueue fib;

   fib.base = (ElemType*)malloc(30*sizeof(ElemType));

   fib.maxSize = 30;

   fib.front = fib.rear = 0;

   for(;fib.rear < k;fib.rear++)

        {

        if(fib.rear<k-1) fib.base[fib.rear] = 0;

        else

         fib.base[fib.rear] = 1;

        }

       while(fib.rear <= n)

        {

           j = 1;

         while(j <= k)

            {

             fib.base[fib.rear] +=fib.base[fib.rear-j];

             j++;

            }

         fib.rear++;

        }

  

    return fib.base[n];

 

}

 

 

/**********

【题目】设A=(a1,,am)B=(b1,,bn)均为有序顺序表,

A'B'分别为AB中除去最大共同前缀后的子表(例如,

A=(x,y,y,z,x,z)B=(x,y,y,z,y,x,x,z),则两者中最大

的共同前缀为(x,y,y,z), 在两表中除去最大共同前缀后

的子表分别为A'=(x,z)B'=(y,x,x,z))。若A'=B'=空表,

A=B;若A'=空表,而B'≠ 空表,或者两者均不为空表,

A'的首元小于B'的首元,则A<B;否则A>B。试写一个比

AB大小的算法。(注意:在算法中,不要破坏原表A

B,也不一定先求得A'B'才进行比较)。

顺序表类型定义如下:

typedef struct {

  ElemType *elem;

  int       length;

  int       size;

  int       increment;

} SqList;

**********/

char Compare(SqList A, SqList B)

/* 比较顺序表AB,      */

/*   返回'<',A<B;    */

/*       '=', A=B;    */

/*       '>', A>B     */

{

     int i;

 if(0 == A.length && 0 == B.length)

        return '=';

 else   

 {

  for(i = 0; i < A.length||i< B.length;i++)

      {

         if(A.elem[i] < B.elem[i])

                 return '<';

         if(A.elem[i] > B.elem[i])

                  return '>';         

         }

  if(A.length > B.length) return '>';

  if(A.length < B.length) return '<';

  return '=';

  

 }

}

 

/**********

【题目】试写一算法,实现顺序表的就地逆置,

即利用原表的存储空间将线性表(a1,a2,,an)

逆置为(an,an-1,,a1)

顺序表类型定义如下:

typedef struct {

  ElemType *elem;

  int       length;

  int       size;

  int       increment;

} SqList;

**********/

void Inverse(SqList &L)

{  int i;

   ElemType temp;

   for(i=0;i<L.length/2;i++) {

   temp=L.elem[i];

   L.elem[i]=L.elem[L.length-1-i];

   L.elem[L.length-1-i]=temp; }

 

}

 

 

/**********

【题目】试对一元稀疏多项式Pn(x)采用存储量同多项式

项数m成正比的顺序存储结构,编写求Pn(x0)的算法(x0

为给定值)。

 

一元稀疏多项式的顺序存储结构:

typedef struct {

  int  coef;  // 系数

  int   exp;  // 指数

} Term;

 

typedef struct {

  Term  *elem;   // 存储空间基址

  int    length; // 长度(项数)

} Poly;

**********/

float Evaluate(Poly P, float x)

/* P.elem[i].coef 存放ai,                        */

/* P.elem[i].exp存放ei (i=1,2,...,m)              */

/* 本算法计算并返回多项式的值。不判别溢出。       */

/* 入口时要求0e1<e2<...<em,算法内不对此再作验证*/

{   int i,j;

    float sum = 0,sum1 ;

    for(i = 0;i <P.length; i++)

    {

        sum1 =  P.elem[i].coef ;

        for(j = 0;j < P.elem[i].exp;j++)

          sum1 =sum1*x;

        sum +=sum1;

    }

    return sum;

 

}

 

/**********

【题目】假设有两个集合AB分别用两个线性表LALB

表示(即:线性表中的数据元素即为集合中的成员),

试写一算法,求并集AAB

顺序表类型定义如下

typedef struct {

  ElemType *elem;     // 存储空间的基址

  int length;    // 当前长度

  int size;      // 存储容量

  int increment; // 空间不够增加空间大小

} SqList;  // 顺序表

可调用顺序表的以下接口函数:   

Status InitList_Sq(SqList &L, int size, int inc); // 初始化顺序表L

int ListLength_Sq(SqList L);  // 返回顺序表L中元素个数

Status GetElem_Sq(SqList L, int i, ElemType &e);

// e返回顺序表L中第i个元素的值

int Search_Sq(SqList L, ElemType e);

// 在顺序表L顺序查找元素e,成功时返回该元素在表中第一次出现的位置,否则返回-1

Status Append_Sq(SqList &L, ElemType e);  // 在顺序表L表尾添加元素e

**********/

void Union(SqList &La, SqList Lb)

{  int i,j;

    ElemType a;

    for(i = 0;i < Lb.length;i++)

        {

         GetElem_Sq(Lb, i+1, a);  

         if( -1 == Search_Sq(La, a))

         Append_Sq(La, a);

        }

    La.length = ListLength_Sq(La);

 

}

 

 

/**********

【题目】试写一算法,实现链栈的判空操作。

链栈的类型定义为:

typedef struct LSNode {

  ElemType data;       // 数据域

  struct LSNode *next; // 指针域

} LSNode, *LStack;    // 结点和链栈类型

***********/

Status StackEmpty_L(LStack S)

/* 对链栈S判空。若S是空栈,则返回TRUE;否则返回FALSE */

{

  if(NULL==S) return TRUE;

  else return FALSE;

}

 

/**********

【题目】试写一算法,实现链栈的取栈顶元素操作。

链栈的类型定义为:

typedef struct LSNode {

  ElemType data;       // 数据域

  struct LSNode *next; // 指针域

} LSNode, *LStack;    // 结点和链栈类型

***********/

Status GetTop_L(LStack S, ElemType &e)

/* 取链栈S的栈顶元素到e,并返回OK; */

/* S是空栈,则失败,返回ERROR。  */

{

     if(NULL==S) return ERROR;

     e = S->data;

     return OK;

  

}

 

/**********

【题目】试写一算法,实现链队列的判空操作。

链队列的类型定义为:

typedef struct LQNode {     

  ElemType  data;  

  struct LQNode  *next;  

} LQNode, *QueuePtr; // 结点和结点指针类型

typedef struct {     

  QueuePtr  front;  // 队头指针

  QueuePtr  rear;   // 队尾指针

} LQueue;  // 链队列类型

***********/

Status QueueEmpty_LQ(LQueue Q)

/* 判定链队列Q是否为空队列。           */

/* Q是空队列,则返回TRUE,否则FALSE*/

{   if(NULL == Q.front) return TRUE;

    else return FALSE;

 

}

 

/**********

【题目】试写一算法,实现链队列的求队列长度操作。

链队列的类型定义为:

typedef struct LQNode {     

  ElemType  data;  

  struct LQNode  *next;  

} LQNode, *QueuePtr; // 结点和结点指针类型

typedef struct {     

  QueuePtr  front;  // 队头指针

  QueuePtr  rear;   // 队尾指针

} LQueue;  // 链队列类型

***********/

int QueueLength_LQ(LQueue Q)

/* 求链队列Q的长度并返回其值*/

{

   LQNode *p = Q.front;

   int i=1;

   if(Q.front == NULL) return ERROR;

   while(p!= Q.rear) {

    p = p->next;

    i++;

   }

   return i;

}

 

/**********

【题目】假设以带头结点的循环链表表示队列,并且

只设一个指针指向队尾元素结点(注意不设头指针)

试编写相应的队列初始化、入队列和出队列的算法。

带头结点循环链队列CLQueue的类型定义为:

typedef struct LQNode {

  ElemType data;

  struct LQNode *next;

} LQNode, *CLQueue;

**********/

Status InitCLQueue(CLQueue &rear) // 初始化空队列

{   LQNode *p;

  if(NULL ==(p = (LQNode*)malloc(sizeof(LQNode))))

   return ERROR;

   p->next = p;

   rear = p;

   return OK;

}

 

Status EnCLQueue(CLQueue &rear, ElemType x) // 入队

{  LQNode *p;

    if(NULL ==(p = (LQNode*)malloc(sizeof(LQNode))))

   return ERROR;

     p->data = x;

     p->next=rear->next;

     rear->next = p;

     rear = p;

      return OK;

}

 

Status DeCLQueue(CLQueue &rear, ElemType &x) // 出队

{   

      if(rear == rear->next )

        return ERROR;

  else

  {

   x = rear->next->next->data;

   rear->next->next = rear->next->next->next;

  }    

  return OK;

}

 

/**********

【题目】试写一算法,实现带头结点单链表的判空操作。

 

单链表的类型定义为:

typedef struct LNode {     

  ElemType  data;  

  struct LNode  *next;  

} LNode, *LinkList; // 结点和结点指针类型

***********/

Status ListEmpty_L(LinkList L)

/* 判定带头结点单链表L是否为空链表。   */

/* L是空链表,则返回TRUE,否则FALSE*/

{

   if(NULL == L->next) return TRUE;

   else return  FALSE;

}

 

/**********

【题目】试写一算法,实现带头结点单链表的销毁操作。

单链表的类型定义为:

typedef struct LNode {     

  ElemType  data;  

  struct LNode  *next;  

} LNode, *LinkList; // 结点和结点指针类型

***********/

Status DestroyList_L(LinkList &L)

/* 销毁带头结点单链表L,并返回OK*/

{

    //if(NULL == L||NULL == L->next) return ERROR

    free(L);

    return OK;

}

 

/**********

【题目】试写一算法,实现带头结点单链表的清空操作。

 

单链表的类型定义为:

typedef struct LNode {     

  ElemType  data;  

  struct LNode  *next;  

} LNode, *LinkList; // 结点和结点指针类型

***********/

Status ClearList_L(LinkList &L)

/* 将带头结点单链表L置为空表,并返回OK*/

/* L不是带头结点单链表,则返回ERROR*/

{  if(L == NULL) return ERROR;

    if(L->next == NULL) return OK;

    L->next  = NULL;

    return OK;

 

}

 

/**********

【题目】试写一算法,实现带头结点单链表的求表长度操作。

单链表的类型定义为:

typedef struct LNode {     

  ElemType  data;  

  struct LNode  *next;  

} LNode, *LinkList; // 结点和结点指针类型

***********/

int ListLength_L(LinkList L)

/* 求带头结点单链表L的长度,并返回长度值。*/

/* L不是带头结点单链表,则返回-1。      */

{  LNode *p;

    int i = 0;

   if(NULL == L) return -1;

   p = L->next;

   while(p != NULL)

   {

     p = p->next;

     i++;

   }

   return i;

}

 

/**********

【题目】试写一算法,在带头结点单链表L插入第i元素e

带头结点单链表的类型定义为:

typedef struct LNode {

  ElemType      data;

  struct LNode *next;

} LNode, *LinkList;

**********/

Status Insert_L(LinkList L, int i, ElemType e)

/* 在带头结点单链表L插入第i元素e,并返回OK*/

/* 若参数不合理,则返回ERROR。              */

{

    if(i == 0 )  return ERROR;  

  LinkList p,q,p1,a,b;

  int j = 0 ,k=0;

  q = (LNode*)malloc(sizeof(LNode)) ;

  q->data = e;

  q->next = NULL;

  p1 = L;

  b=L;

  while(b !=NULL)

  {

    a =  b;

    b = a->next;

    k++;

  }

  if(k < i )  return ERROR;

  while(j <i)

  {

  

    p =  p1;

    p1 = p->next;

      j++;

   

    

  }

 q->next = p->next;

  p->next =  q;

  return OK;

}

 

/**********

【题目】试写一算法,在带头结点单链表删除第i元素到e

带头结点单链表的类型定义为:

typedef struct LNode {

  ElemType      data;

  struct LNode *next;

} LNode, *LinkList;

**********/

Status Delete_L(LinkList L, int i, ElemType &e)

/* 在带头结点单链表L删除第i元素到e,并返回OK*/

/* 若参数不合理,则返回ERROR。                */

{

    LinkList p,q1,q2,q3;

    int j=0;

    p=L;

    while(p->next){

     q1 = p;

     p=q1->next;

     if(j==i-1)

     {

       q2 = q1;

       q3 = p;

     }

      ++j;

    }  

   if(i== 0||j<i) return ERROR;

    e = q3->data;

    q2->next = q3->next;

    return OK;

}

 

/**********

【题目】试写一算法,在带头结点单链表的第i元素起的

所有元素从链表移除,并构成一个带头结点的新链表。

带头结点单链表的类型定义为:

typedef struct LNode {

  ElemType      data;

  struct LNode *next;

} LNode, *LinkList;

**********/

Status Split_L(LinkList L, LinkList &Li, int i)

/* 在带头结点单链表L的第i元素起的所有元素*/

/* 移除,并构成带头结点链表Li,返回OK。   */

/* 若参数不合理,则LiNULL,返回ERROR。  */

{     

      if(i<=0||L==null) {

     Li==null;

     return ERROR;

     }

   LinkList a,b,c;

   int j=0,k=0;

   Li=(LNode*)malloc(sizeof(LNode));

   Li->next=null;

   a=L;

   b=L;

   while(a->next!=null){

     j++;

     a=a->next;

   }

   if(j<i) {

   Li=null;

   return ERROR;

   }

   while(k<i-1){

   b=b->next;

   k++;

   }

  c=b->next;

  Li->next=c;

  b->next=null;

  return OK;

   

}

 

/**********

【题目】试写一算法,在带头结点单链表删除第i元素

起的所有元素。

带头结点单链表的类型定义为:

typedef struct LNode {

  ElemType      data;

  struct LNode *next;

} LNode, *LinkList;

**********/

Status Cut_L(LinkList L, int i)

/* 在带头结点单链表L删除第i元素起的所有元素,并返回OK*/

/* 若参数不合理,则返回ERROR。                         */

{    LinkList p1,p2,p3;

    int j=0,k=0;

    p2 =L;

    p1=L;

    p3=L;

    if(NULL == L||L->next ==NULL) return ERROR;

     while(p3->next!=null){

       p3=p3->next;

       j++;

     }

     if(j < i||i==0) return ERROR;

     

      while(k<i){

       p1=p2;

       p2=p1->next;

       k++;

     }

      p1->next=null;

      return OK;

}

 

/**********

【题目】试写一算法,删除带头结点单链表中所有值

x的元素,并释放被删结点空间。

单链表类型定义如下:

typedef struct LNode {

  ElemType      data;

  struct LNode *next;

} LNode, *LinkList;

**********/

Status DeleteX_L(LinkList L, ElemType x)

/* 删除带头结点单链表L中所有值为x的元素,      */

/* 并释放被删结点空间,返回实际删除的元素个数。*/

{   LinkList p1,p2,p3;

    int j = 0;

    if(NULL ==L) return ERROR;

    p1=p2=L;

    while(p2!=NULL){

      p2 = p1->next;

      if(p2->data == x){

        p3 = p2;

        p2 = p3->next;

        p1->next = p2;

        free(p3);

        j++;

      }

      else if(p2->data!=x)

       {

          p1 = p2;

          p2 = p1->next;

       }

      

      

    }

    

    return j;

}

 

/**********

【题目】试写一算法,删除带头结点单链表中所有值

小于x的元素,并释放被删结点空间。

单链表类型定义如下:

typedef struct LNode {

  ElemType      data;

  struct LNode *next;

} LNode, *LinkList;

**********/

Status DeleteSome_L(LinkList L, ElemType x)

/* 删除带头结点单链表L中所有值小于x的元素,    */

/* 并释放被删结点空间,返回实际删除的元素个数。*/

{     LinkList p1,p2,p3;

    int j = 0; p1=p2=L;

    if(NULL == p1) return j;

    

    while(p2!=NULL){

      p2 = p1->next;

      if(p2->data < x &&p2!=null){

        p3 = p2;

        p2 = p3->next;

        p1->next = p2;

        free(p3);

        j++;

      }

      else if(p2->data >= x)

       {

          p1 = p2;

          p2 = p1->next;

       }

      

      

    }

    

    return j;

 

}

 

/**********

【题目】试以顺序表LL.rcd[L.length+1]作为监视哨,

改写教材5.2节中给出的升序直接插入排序算法。

顺序表的类型RcdSqList定义如下:

typedef struct {

   KeyType key;

   ...

} RcdType;

typedef struct {

   RcdType rcd[MAXSIZE+1]; // r[0]闲置

   int length;

} RcdSqList;

**********/

void InsertSort(RcdSqList &L)

{

   int i,j;

   for(i = 1; i<L.length; i++){

     if(L.rcd[i+1].key < L.rcd[i].key) {

       L.rcd[0] = L.rcd[i+1];

       j = i+1;

       do{

         j--;L.rcd[j+1] = L.rcd[j];

       } while(L.rcd[0].key<L.rcd[j-1].key);

       L.rcd[j] = L.rcd[0];

     }

   }

   

}

 

 

/**********

【题目】如下所述,改写教材1.5节的冒泡排序算法:

将算法中用以起控制作用的布尔变量change改为一个整型

变量,指示每一趟排序中进行交换的最后一个记录的位置,

并以它作为下一趟起泡排序循环终止的控制值。

顺序表的类型RcdSqList定义如下:

typedef struct {

   KeyType key;

   ...

} RcdType;

typedef struct {

   RcdType rcd[MAXSIZE+1]; // r[0]闲置

   int length;

} RcdSqList;

**********/

void BubbleSort(RcdSqList &L)

/* 元素比较和交换必须调用如下定义的比较函数和交换函数:*/

/* Status LT(RedType a, RedType b);   比较:"<"        */

/* Status GT(RedType a, RedType b);   比较:">"        */

/* void Swap(RedType &a, RedType &b); 交换             */

{  int i,change,j,k;                                                  

   for(i = L.length,change = 0;i>1;i--)

      {

       change = i;

      for(j = 1;j<i;++j)

        {

        if(GT(L.rcd[j],L.rcd[j+1]))

           {

            Swap(L.rcd[j],L.rcd[j+1]);

            k++;

            change = j+1;

            }

            

        }

       while(L.rcd[change].key == L.rcd[change-1].key)

            {            //while来跳过那些相同关键字

             change = change - 1;

            }

      i = change;

       if(k == 0) i = 1; //当有一次比较没有交换时使i= 1结束操作

     

     k=0;

      }

}

 

/**********

【题目】已知记录序列L.rcd[1..L.length]中的关键

字各不相同,可按如下所述实现计数排序:另设数组

c[1..n],对每个记录a[i], 统计序列中关键字比它

小的记录个数存于c[i],则c[i]=0的记录必为关键字

最小的记录,然后依c[i]值的大小对序列中记录进行

重新排列。试编写算法实现上述排序方法。

顺序表的类型RcdSqList定义如下:

typedef struct {

   KeyType key;

   ...

} RcdType;

typedef struct {

   RcdType rcd[MAXSIZE+1]; // r[0]闲置

   int     length;

} RcdSqList;

**********/

void CountSort(RcdSqList &L)

/* 采用顺序表存储结构,在函数内自行定义计数数组c */

{

   int k = L.length ;

  RcdSqList L1;

  int c[27];

  int i,j;

  for(i = 1;i <= L.length ;i++)

     for(j = 1;j <= L.length;j++)

        {

         if(L.rcd[i].key<L.rcd[j].key)

            c[i]++;

        }

        

    for(i = 1;i<=L.length ;i++)

        {

         L1.rcd[c[i]+1].key = L.rcd[i].key;

        }

    for(i = 1;i<=L.length ;i++)

        {

         L.rcd[L.length-i+1].key = L1.rcd[i].key;

        }

}

 

 

/**********

【题目】已知某哈希表的装载因子小于1,哈希函数H(key)

为关键字(标识符)的第一个字母在字母表中的序号,处理

冲突的方法为线性探测开放定址法。试编写一个按第一个

字母的顺序输出哈希表中所有关键字的算法。

哈希表的类型HashTable定义如下:

#define SUCCESS    1

#define UNSUCCESS  0

#define DUPLICATE -1

typedef char StrKeyType[4];

typedef struct {

   StrKeyType key; // 关键字项

   int    tag;     // 标记 0:空;1:有效; -1:已删除

   void  *any;     // 其他信息

} RcdType;

typedef struct {

  RcdType *rcd;    // 存储空间基址

  int      size;   // 哈希表容量

  int      count;  // 表中当前记录个数

} HashTable;

**********/

void PrintKeys(HashTable ht, void(*print)(StrKeyType))

/* 依题意用print输出关键字*/

{

     int n,i,size;

    char c;    

    for(c='A';c<='Z';c++){

    for(i=0;i<ht.size;i++){

    if(ht.rcd[i].tag==-1) continue;

    if(ht.rcd[i].key[0]==c)

    print(ht.rcd[i].key);

    }

   }

}

 

 

/**********

【题目】假设哈希表长为m,哈希函数为H(x),用链地址法

处理冲突。试编写输入一组关键字并建造哈希表的算法。

哈希表的类型ChainHashTab定义如下:

#define NUM         7

#define NULLKEY    -1

#define SUCCESS     1

#define UNSUCCESS   0

#define DUPLICATE  -1

typedef char HKeyType;

typedef struct HNode {

   HKeyType  data;

   struct HNode*  next;

}*HLink;

typedef struct {

   HLink  *rcd;   // 指针存储基址,动态分配数组

   int    count;  // 当前表中含有的记录个数

   int    size;  // 哈希表的当前容量

}ChainHashTab;    // 链地址哈希表

int Hash(ChainHashTab H, HKeyType k) { // 哈希函数

  return k % H.size;

}

Status Collision(ChainHashTab H, HLink &p) {

  // 求得下一个探查地址p

  if (p && p->next) {

    p = p->next;

    return SUCCESS;

  } else return UNSUCCESS;

}

**********/

int BuildHashTab(ChainHashTab &H, int n, HKeyType es[])

/* 直接调用下列函数                             */

/* 哈希函数:                                   */

/*    int Hash(ChainHashTab H, HKeyType k);     */

/* 冲突处理函数:                               */

/*    int Collision(ChainHashTab H, HLink &p);  */

{

    int i,k,j;

  HLink p,q,p1;

  H.rcd = (HLink*)malloc(7*sizeof(HLink));

  H.size = 7;

  H.count = 0;

  for(i = 0;es[i] >= 'A';i++)

    {

     p = (HNode*)malloc(sizeof(HNode));

     p->next = NULL;

     p->data = es[i];

     k = Hash( H, p->data) ;

     if(NULL !=H.rcd[k])

        {  // 判断其中是否有相同的HKeyType

         p1 =  H.rcd[k];

         while(NULL != p1)

         {  //j作为标记,如果j = 0表示没有相同的,插入p

           if(p1->data == p->data)

                j = 1;

           p1 = p1->next;

         }

         if(j == 0)

            {

             q =  H.rcd[k];

             p->next = q;

             H.rcd[k] = p;

           

             }

           j = 0;

        }         

     else   

        H.rcd[k] = p; //为什么H.rcd[k]->next = p;不会报错

    H.count++;

    }

}

 

/**********

【题目】试编写如下定义的递归函数的递归算法:

    g(m,n) = 0             m=0,n>=0

    g(m,n) = g(m-1,2n)+n   m>0,n>=0

**********/

int G(int m, int n)

/* 如果 m<0n<0则返回-1 */

{  

    if(m<0||n<0)

    return -1;

    else if(m==0&&n>=0)

     return 0;

     else if(m>0&&n>=0)

       return G(m-1,2*n)+n;

 

}

 

/**********

【题目】试写出求递归函数F(n)的递归算法:

    F(n) = n+1      n=0

    F(n) = nF(n/2)  n>0

**********/

int F(int n)

/* 如果 n<0则返回-1 */

{   if(n<0) return -1;

    else if(n==0) return n+1;

    else if(n>0) return n*F(n/2);

 

}

 

/**********

【题目】求解平方根 的迭代函数定义如下:

  sqrt(A,p,e) = p                   |p*p-A|<e

  sqrt(A,p,e) = sqrt(A,(p+A/p)/2,e) |p*p-A|>=e

其中,pA的近似平方根,e是结果允许误差。试写出相

应的递归算法。

**********/

float Sqrt(float A, float p, float e)

{   if(fabs(p*p-A)<e)

      return p;

   else

      return Sqrt(A,(p+A/p)/2,e);

}

 

/**********

【题目】已知Ackerman函数的定义如下:

   akm(m,n) = n+1                 m=0

   akm(m,n) = akm(m-1,1)          m!=0,n=0

   akm(m,n) = akm(m-1,akm(m,n-1)) m!=0,n!=0

请写出递归算法。

**********/

int Akm(int m, int n)

/* m<0n<0则返回-1  */

{  if(m<0||n<0) return -1;

if(m==0) return n+1;

    else if(m!=0&&n==0)

    return Akm(m-1,1);

    else if(m!=0&&n!=0)

    return Akm(m-1,Akm(m,n-1)) ;

 

}

 

/**********

【题目】试写出求递归函数F(n)的非递归算法:

    F(n) = n+1      n=0

    F(n) = nF(n/2)  n>0

**********/

int F(int n)

/* 如果 n<0则返回-1 */

{   int i = n,count=1;

    if(n<0) return -1;

    else if(n==0) return n+1;

    else

        for(;i>0;i=i/2)

         count = count*i ;

    return count;     

}

 

/**********

【题目】求解平方根 的迭代函数定义如下:

  sqrt(A,p,e) = p                   |p*p-A|<e

  sqrt(A,p,e) = sqrt(A,(p+A/p)/2,e) |p*p-A|>=e

其中,pA的近似平方根,e是结果允许误差。试写出相

应的非递归算法。

**********/

float Sqrt(float A, float p, float e)

{   float mp=p;

    if(fabs(p*p-A)<e)

      return p;

      else

         while(fabs(mp*mp-A)>=e)

         {

           mp=(mp+A/mp)/2 ;

         }

         return mp;

         

}

 

/**********

【题目】假设以二维数组g[1..m][1..n]表示一个图像

区域,g[i][j]表示该区域中点(i,j)所具颜色,其值

为从0k的整数。试编写递归算法,将点(i0,j0)所在

区域的颜色置换为颜色c。约定与(i0,j0)同色的上、

下、左、右的邻接点为同色区域的点。

 

表示图像区域的类型定义如下:

typedef char GTYPE[m+1][n+1];

**********/

void ChangeColor(GTYPE g, int m, int n,

                 char c, int i0, int j0)

/* g[1..m][1..n]中,将元素g[i0][j0] */

/* 所在的同色区域的颜色置换为颜色c    */

{

   if(i0>m||j0>n)//初次调用时下标不合法  

     {  

         return;  

     }  

     int color;  

     color=g[i0][j0];  

     g[i0][j0]=c;  

     if(i0-1>=1)//判断是否越界,下同  

     {  

         if(g[i0-1][j0]==color)  

         {  

             ChangeColor(g,m,n,c,i0-1,j0);          

         }  

     }  

     if(i0+1<=m)  

     {  

         if(g[i0+1][j0]==color)  

         {  

             ChangeColor(g,m,n,c,i0+1,j0);      

         }     

     }   

     if(j0-1>=1)  

     {  

         if(g[i0][j0-1]==color)  

         {  

             ChangeColor(g,m,n,c,i0,j0-1);      

         }  

     }  

     if(j0+1<=n)      

     {  

         if(g[i0][j0+1]==color)  

         {      

             ChangeColor(g,m,n,c,i0,j0+1);      

         }  

     }   

}

 

/**********

【题目】若两棵二叉树T1T2皆为空,或者皆不空

T1的左、右子树和T2的左、右子树分别相似,则

称二叉树T1T2相似。试编写算法,判别给定两棵

二叉树是否相似。

二叉链表类型定义:

typedef struct BiTNode {

  TElemType  data;

  struct BiTNode  *lchild, *rchild;

} BiTNode, *BiTree;

**********/

Status Similar(BiTree T1, BiTree T2)

/* 判断两棵二叉树是否相似的递归算法 */

{   if(T1==null&&null==T2) return true;

    else if(T1&&T2){

      if(ERROR==  Similar(T1->lchild, T2->lchild))return ERROR;

      if(ERROR==  Similar(T1->rchild, T2->rchild))return ERROR;

    }else return ERROR;

     return true;

}

 

/**********

【题目】编写递归算法,求对二叉树T先序遍历时

k个访问的结点的值。

二叉链表类型定义:

typedef struct BiTNode {

  TElemType data;

  struct BiTNode  *lchild, *rchild;

} BiTNode, *BiTree;

**********/

TElemType PreOrderK(BiTree T, int k)

/* 求对二叉树T先序遍历时第k个访问的结点的值。*/

/* 若失败,则返回'#'                         */

{  

     

    int i=0,count=0;  //i为循环变量、count为记录根结点的左子树的结点个数

    TElemType d;      //定义一个返回值变量d

    BiTree a[20],b;   //a[20]记录左子树的根结点,b为一个中间变量

    if(k<=0||!T) return '#'; //k0或者T空时,没有找到结点,返回'#'

    if(k==1) return T->data; //k从给定的数减到1时,表示找到,返回bt->data

    d=PreOrderK(T->lchild,k-1); //左子树递归

    if(d!='#')  //当找到T时,返回T

        return(d);

    b=T->lchild; //没有找到,继续找

    while(b||i)   //下面是计算左子树有多少个结点的算法,并记录在count

    {

        if(b)    //当左子树非空时,

        {

            a[i]=b;  //记录第i个结点在a[i]中,用来计算本结点的右子树用的

            i++;     //计算下一个结点的序号

            b=b->lchild;  //对下一个结点操作

            count++;      //记录结点数

            }

        else

        {

            i--;   //如果b空,表示执行到最左的叶子,现在要找到上一个结点的右子树

            b=a[i]; //把上一个结点赋给b

            b=b->rchild; //使b指向右子树

        }

    }

    d=PreOrderK(T->rchild,k-count-1); //递归右子树,并返回k-count-1,表示要找的结点可能在右子树的第k-count-1的位置

    if(d!='#')    //T判断,当T不为'#'时,表示找到,返回T

        return (d);

    else         //否则返回 '#'表示没有找到

        return '#';    

}

 

/**********

【题目】编写递归算法,计算二叉树T中叶子结点的数目。

二叉链表类型定义:

typedef struct BiTNode {

  TElemType  data;

  struct BiTNode  *lchild, *rchild;

} BiTNode, *BiTree;

**********/

 

int Leaves(BiTree T)

/* 计算二叉树T中叶子结点的数目*/

{ if(!T) return 0; /*空树没有叶子*/

  else if(!T->lchild&&!T->rchild) return 1; /*叶子结点*/

  else return Leaves(T->lchild)+Leaves(T->rchild);/*左子树的叶子数加上右子树的叶子数*/

   

}

 

 

/**********

【题目】试利用栈及其基本操作写出二叉树T的非递归

的先序遍历算法。

二叉链表类型定义:

typedef struct BiTNode {

  TElemType  data;

  struct BiTNode  *lchild,*rchild;

} BiTNode, *BiTree;

可用栈类型Stack的相关定义:

typedef BiTree SElemType;   // 栈的元素类型

Status InitStack(Stack &S);

Status StackEmpty(Stack S);

Status Push(Stack &S, SElemType e);

Status Pop(Stack &S, SElemType &e);

Status GetTop(Stack S, SElemType &e);

**********/

 

void PreOrder(BiTree T, void (*visit)(TElemType))

/* 使用栈,非递归先序遍历二叉树T,     */

/* 对每个结点的元素域data调用函数visit */

{   Stack s;

    InitStack(s);    

    BiTree p = T;

    while(p){

      visit(p->data);

      if(p->rchild)

            Push(s,p->rchild);

      if(p->lchild)

            p = p->lchild;

       else

         if(StackEmpty(s)!=true) Pop(s, p);

         else

            p = null;

    }

 

}

 

 

/**********

【题目】试利用栈及其基本操作写出二叉树T的非递归

的后序遍历算法(提示:为分辨后序遍历时两次进栈的

不同返回点,需在指针进栈时同时将一个标志进栈)。

二叉链表类型定义:

typedef struct BiTNode {

  TElemType  data;

  struct BiTNode  *lchild,*rchild;

} BiTNode, *BiTree;

可用栈类型Stack的相关定义:

typedef struct {

  struct BiTNode *ptr; // 二叉树结点的指针类型

  int      tag; // 0..1

} SElemType;    // 栈的元素类型

Status InitStack(Stack &S);

Status StackEmpty(Stack S);

Status Push(Stack &S, SElemType e);

Status Pop(Stack &S, SElemType &e);

Status GetTop(Stack S, SElemType &e);

**********/

void PostOrder(BiTree bt, void (*visit)(TElemType))

/* 使用栈,非递归后序遍历二叉树T,     */

/* 对每个结点的元素域data调用函数visit */

{

    Stack S;

    InitStack(S);

    SElemType e;

    BiTree p=bt;

    int tag=0;

    if(bt){

        e.tag=0;

        while(!StackEmpty(S)||p==bt){

            while(p&&!tag){

                e.ptr=p;

                if(p->lchild){//如果存在左子树

                p=p->lchild;

                e.tag=0;

                }

                else{//否则为右子树

                p=p->rchild;

                e.tag=1;

                }

            Push(S,e);

        }//while

        GetTop(S,e);

        if(!StackEmpty(S)&&e.tag){

            Pop(S,e); //叶子结点出栈

            p=e.ptr;

            visit(p->data);//输出该结点

        }

        if(!StackEmpty(S)){

            Pop(S,e); //得到上一层结点

            p=e.ptr;

            if(e.tag){//右子树已经入栈

                visit(p->data);

                p=NULL;

            }

            else{//右子树没入过栈

                if(p->rchild){

                    p=p->rchild;

                    tag=0;

                    e.tag=1;

                    Push(S,e);

                }

                else{//没有右子树

                    visit(p->data);

                    p=NULL;

                }

            }

        }

        else{//栈空则,pNULL

            p=NULL;

        }

    }//while

  }//if

}

 

 

/**********

【题目】二叉树采用三叉链表的存储结构,试编写

不借助栈的非递归中序遍历算法。

三叉链表类型定义:

typedef struct TriTNode {

  TElemType data;

  struct TriTNode  *parent, *lchild, *rchild;

} TriTNode, *TriTree;

**********/

void InOrder(TriTree PT, void (*visit)(TElemType))

/* 不使用栈,非递归中序遍历二叉树PT,  */

/* 对每个结点的元素域data调用函数visit */

{

    TriTree p,pr;

 if(PT!=NULL)

 {

    p = PT;

    while(p!=NULL)

    { if(p->lchild==NULL) visit(p->data);

         //输出有右子树的结点

      if(p->lchild)  p = p->lchild;

      else

          if(p->rchild)  p = p->rchild;

          else

          {

            

           do{

                pr = p;                 

                p = p->parent;

                if(p->rchild!=pr)  //如果prp的右子树则不输出

                     visit(p->data);

              }while(p!=NULL&&(p->rchild==pr||NULL==p->rchild));

           if(p!=NULL)   p = p->rchild;

          }

    }

 }

}

 

/**********

【题目】假设在三叉链表的结点中增设一个标志域

(mark取值0,12)以区分在遍历过程中到达该结点

时应继续向左或向右或访问该结点。试以此存储结

构编写不用栈辅助的二叉树非递归后序遍历算法。

带标志域的三叉链表类型定义:

typedef struct TriTNode {

  TElemType  data;

  struct TriTNode  *lchild, *rchild, *parent;

  int       mark;  // 标志域

} TriTNode, *TriTree;

**********/

void PostOrder(TriTree T, void (*visit)(TElemType))

/* 不使用栈,非递归后序遍历二叉树T,   */

/* 对每个结点的元素域data调用函数visit */

{

     TriTree p,pr;

 if(T!=NULL)

 {

    p = T;

    while(p!=NULL)

    {

      if(p->lchild)  p = p->lchild;

      else

          if(p->rchild)  p = p->rchild;

          else

          {

           do{

             pr = p;

             visit(pr->data);

             p = p->parent;             

           }while(p!=NULL&&(p->rchild==pr||NULL==p->rchild));

           if(p!=NULL)   p = p->rchild;

          }

    }

 }

 

}

 

 

/**********

【题目】编写递归算法,将二叉树中所有结点的

左、右子树相互交换。

二叉链表类型定义:

typedef struct BiTNode {

  TElemType data;

  struct BiTNode  *lchild, *rchild;

} BiTNode, *BiTree;

**********/

void ExchangeSubTree(BiTree &T)

/* 将二叉树中所有结点的左、右子树相互交换 */

{    BiTree p;

    if(!T) return;

    if(T->lchild) ExchangeSubTree(T->lchild);

    if(T->rchild) ExchangeSubTree(T->rchild);

    p = T->lchild;

    T->lchild = T->rchild;

    T->rchild = p;

     

}

 

/**********

【题目】编写递归算法:求二叉树中以元素值

x的结点为根的子树的深度。

二叉链表类型定义:

typedef struct BiTNode {

  TElemType data;

  struct BiTNode  *lchild, *rchild;

} BiTNode, *BiTree;

**********/

int BirTreeDepth(BiTree T){

  int depthLeft,depthRight;

  if(null==T) return 0;

  else {

    depthLeft = BirTreeDepth(T->lchild);

    depthRight = BirTreeDepth(T->rchild);

    return 1+(depthLeft > depthRight?depthLeft:depthRight);

  }

}

int Findx(BiTree T,BiTree &p,TElemType x){

if(T){

if(T->data==x){

p=T;

return 0;

}

else{

Findx(T->lchild,p,x);

Findx(T->rchild,p,x);

}

}

}

 

int Depthx(BiTree T, TElemType x)

/* 求二叉树中以值为x的结点为根的子树深度*/

{

    BiTree p=NULL;

Findx(T,p,x);

return BirTreeDepth(p);

}

 

 

/**********

【题目】编写递归算法:对于二叉树中每一个元素值为x

的结点,删去以它为根的子树,并释放相应的空间。

二叉链表类型定义:

typedef struct BiTNode {

  TElemType data;

  struct BiTNode  *lchild, *rchild;

} BiTNode, *BiTree;

**********/

void Destroy(BiTree &T){

 if(T){

    Destroy(T->lchild);

    Destroy(T->rchild);

    free(T);

 }

}

/*BiTree find(BiTree &T, char x){

   if(!T) return null;

   if(T->data == x) return T;

   find(T->lchild,x); find(T->rchild,x);

}       */

 

void ReleaseX(BiTree &T, char x)

/* 对于二叉树T中每一个元素值为x的结点,*/

/* 删去以它为根的子树,并释放相应的空间 */

{   

    if(!T) return ;

    if(T->data==x)

    Destroy(T);

    ReleaseX(T->lchild, x);

      ReleaseX(T->rchild, x);

 

}

 

/**********

【题目】编写复制一棵二叉树的递归算法。

二叉链表类型定义:

typedef char TElemType; // 设二叉树的元素为char类型

typedef struct BiTNode {

  TElemType data;

  struct BiTNode  *lchild, *rchild;

} BiTNode, *BiTree;

**********/

void CopyBiTree(BiTree T, BiTree &TT)

/* 递归复制二叉树T得到TT */

{   

    if(!T) return ;

     TT = (BiTree)malloc(sizeof(BiTNode));

     if(!TT) return ;

     TT->data = T->data;

     if(T->lchild) CopyBiTree(T->lchild,TT->lchild);

     if(T->rchild) CopyBiTree(T->rchild,TT->rchild);

}

 

/**********

【题目】编写算法判别给定二叉树是否为完全二叉树。

二叉链表类型定义:

typedef struct BiTNode {

  TElemType data;

  struct BiTNode  *lchild, *rchild;

} BiTNode, *BiTree;

可用队列类型Queue的相关定义:

typedef BiTree QElemType; // 设队列元素为二叉树的指针类型

Status InitQueue(Queue &Q);

Status EnQueue(Queue &Q, QElemType e);

Status DeQueue(Queue &Q, QElemType &e);

Status GetHead(Queue Q, QElemType &e);

Status QueueEmpty(Queue Q);

**********/

 

Status CompleteBiTree(BiTree bt)

/* 判别二叉树T是否为完全二叉树*/

{  Queue Q;

     QElemType p;

     int tag=0;

     EnQueue(Q,bt);

     while(!QueueEmpty(Q))

     {

       DeQueue(Q,p);

       if(!p) tag=1;       //如果到最后输出都为空,表示已经遍历完成,确认是完全树

       else if(tag) return ERROR;

       else

       {

       EnQueue(Q,p->lchild);

       EnQueue(Q,p->rchild);

       }

     }

     return OK;

}

 

/**********

【题目】试编写一个二叉排序树的判定算法。

二叉排序树的类型BSTree定义如下:

typedef struct {

  KeyType key;  

  ... ...   // 其他数据域

} TElemType;

typedef struct BiTNode {

  TElemType data;

  struct BSTNode  *lchild, *rchild;

}BSTNode, *BSTree;

**********/

Status IsBSTree(BSTree t)

/* 判别二叉树T是否为二叉排序树。*/

/* 若是,则返回TRUE,否则FALSE  */

{

    BSTree p,q;

 if(t)

  {    p=t->lchild;

       q=t->rchild;

  if(p&&p->data.key>=t->data.key)

    return FALSE;

  if(q&&q->data.key<=t->data.key)

    return FALSE;

  

    if (IsBSTree(p))

     return IsBSTree(q);

     return FALSE;

  

  }

  return TRUE;

}

 

/**********

【题目】编写递归算法,从大到小输出给定二叉排序树

中所有关键字不小于x的数据元素。

二叉排序树的类型BSTree定义如下:

typedef struct {

    KeyType key;  

    ... ...   // 其他数据域

} TElemType;

typedef struct BSTNode {

  TElemType  data;

  struct BSTNode  *lchild,*rchild;

}BSTNode, *BSTree;

**********/

void OrderOut(BSTree t, KeyType x, void(*visit)(TElemType))

/* 调用visit(T->data)输出  */

{  KeyType key = t->data.key;

    

    if(!t)

    {

        return;

    }

    if(key>=x)

    {          

        OrderOut(t->rchild,x,visit);

        visit(t->data);

        OrderOut(t->lchild,x,visit);

    }

    else

    {

        OrderOut(t->rchild,x,visit);

    }

}

 

/**********

【题目】试写一非递归算法,在二叉查找树T中插入元素e

二叉查找树的类型BSTree定义如下:

typedef struct {

  KeyType key;  

    ... ...   // 其他数据域

} TElemType;

typedef struct BSTNode {

  TElemType data;

  struct BSTNode  *lchild,*rchild;

} BSTNode, *BSTree;

**********/

Status InsertBST_I(BSTree &T, TElemType k)

/* 在二叉查找树T中插入元素e的非递归算法*/

{  BSTree p,L,q = T ;

  p = (BSTree)malloc(sizeof(BSTNode));

  if(p == NULL)   return FALSE;

  p->data = k;  p->lchild = NULL; p->rchild = NULL;

  while(q!=NULL)

  {

    if(q->data.key == k.key)   return FALSE;

    if(q->data.key > k.key)

        {

         if(q->lchild!=NULL)    q = q->lchild;        

          else                  q->lchild = p;

        }

    if(q->data.key < k.key)

        {

         if(q->rchild!=NULL)    q = q->rchild;

          else                  q->rchild = p;

         }

  }

 

}

 

/**********

【题目】试编写算法,求二叉树T中结点ab的最近共同祖先。

二叉链表类型定义:

typedef struct BiTNode {

  TElemType data;

  struct BiTNode  *lchild,*rchild;

} BiTNode, *BiTree;

可用栈类型Stack的相关定义:

typedef struct {

  BiTNode *ptr; // 二叉树结点的指针类型

  int      tag; // 0..1

} SElemType;      // 栈的元素类型

Status InitStack(Stack &S);

Status StackEmpty(Stack S);

int StackLength(SqStack S);

Status Push(Stack &S, SElemType e);

Status Pop(Stack &S, SElemType &e);

Status GetTop(Stack S, SElemType &e);

**********/

 void findElem(BiTree T,TElemType e,Stack &s)

{

    BiTree t=T;

    BiTNode *bip;

    SElemType se;

    while(t)

    {

        while(t->lchild)

        {

            if(t->data==e) return ;

            se.ptr=t;se.tag=1;

            Push(s,se);            

            t=t->lchild;

        }

        if(t->data==e) return ;

        if(t->rchild) {se.ptr=t;se.tag=1;Push(s,se);t=t->rchild;}

        else

        {

            bip=t;Pop(s,se);t=se.ptr;

            while(t->rchild==bip||!t->rchild)

            {

                bip=t;

                if(t!=T) {Pop(s,se);t=se.ptr;}

                else return;

            }

            se.ptr=t;se.tag=1;

            Push(s,se);

            t=t->rchild;

        }

    }

}

 

 

 

BiTree CommAncestor(BiTree T, TElemType a, TElemType b)

/* 求二叉树T中结点ab的最近共同祖先*/

{   Stack sa,sb,st;

    SElemType sea,seb;

    BiTree bi,bii;

      

    InitStack(sa);InitStack(sb);InitStack(st);

    findElem(T,a,sa);

    findElem(T,b,sb);

 

    while(!StackEmpty(sa))

    {

        Pop(sa,sea);

        bi=sea.ptr;

        st=sb;

        while(!StackEmpty(st))

        {

            Pop(st,seb);

            bii=seb.ptr;

            if(bi->data==bii->data)return bi;

        }

    }

 

}

 

 

/**********

【题目】在二叉排序树的每个结点中增设一个lsize域,

其值为该结点的左子树中的结点数加1。试编写时间复杂

度为O(logn)的算法,求树中第k小的结点的位置。

二叉排序树的类型BSTree定义如下:

typedef char KeyType;

 

typedef struct BSTNode {

  KeyType key;

  struct BSTNode  *lchild,*rchild;

  int lsize; // 新增域,值为左子树的结点数+1

} BSTNode, *BSTree;

**********/

 

 

BSTNode *Ranking(BSTree T, int k)

/* 在含lsize域的二叉排序树T中,*/

/* 求指向T中第k小的结点的指针  */

{  if(!T) return null;

    if(T->lsize==k) return T;

    else if(T->lsize>k) return Ranking(T->lchild, k) ;

         else return Ranking(T->rchild, k-T->lsize);

   

}

 

/**********

【题目】假设二叉排序树T的每个结点的平衡因子域bf当前

均为0。试编写算法,求二叉排序树T的深度,并为每个结点

bf域赋予正确的平衡因子值。

平衡二叉排序树的类型BBSTree定义如下:

typedef char KeyType;

typedef struct BBSTNode {

  KeyType key;

  int bf;    // 平衡因子

  struct BBSTNode  *lchild,*rchild;

} BBSTNode, *BBSTree;

**********/

/*int depth(BBSTree t){

     int l;

     int r;

     if(!t) return 0;

     else {

       l = depth(t->lchild);

       r = depth(t->rchild);

       return 1+(l>r?l:r);

     }

}  */

 

int Depth_BF(BBSTree T)

/* 求二叉排序树T的深度,并为每个结点*/

/* bf域赋予正确的平衡因子值。      */

{   int l,r;

    if(!T) return 0;

    else {

     l = Depth_BF(T->lchild);

     r = Depth_BF(T->rchild);

     T->bf = l-r;

    return 1+(l>r?l:r);

    }

}

 

 

/**********

【题目】编写平衡二叉排序树的右平衡处理算法。

平衡二叉排序树的类型BBSTree定义如下:

typedef char KeyType;  

typedef struct BBSTNode {

  KeyType key;

  int  bf;    // 平衡因子

  struct BBSTNode  *lchild,*rchild;

} BBSTNode, *BBSTree;

可调用下列旋转调整操作:

void L_Rotate(BBSTree &p); // 对最小失衡子树p做左旋调整

void R_Rotate(BBSTree &p); // 对最小失衡子树p做右旋调整

**********/

 

void RightBalance(BBSTree &T)

/* 实现对二叉树T的右平衡处理*/

{

    BBSTree lc,rd;

   rd = T->rchild;

   switch(rd->bf){

       case RH:

            T->bf = rd->bf = EH; L_Rotate(T); break;

       case LH:

            lc = rd->lchild;

            switch(lc->bf){

              case LH: T->bf = EH;  lc->bf = EH; break;

              case EH: T->bf = rd->bf = EH;break;

              case RH: T->bf=LH; lc->bf = EH; break;

            }

           lc->bf=EH;

           R_Rotate(T->rchild);

           L_Rotate(T);

           break;

   }

 

}

 

/**********

【题目】试编写算法,对一棵以孩子兄弟链表表示

的树统计叶子的个数。

孩子兄弟链表类型定义:

typedef struct CSTNode {

  TElemType  data;

  struct CSTNode  *firstChild, *nextSibling;

} CSTNode, *CSTree;

**********/

void Count(CSTree T, int &n){

   if(T){

     if(!T->firstChild) n++;

     Count(T->firstChild, n);

     Count(T->nextSibling, n);

   }

}

 

int Leave(CSTree T) /* 统计树T的叶子数*/

{   

    int n =0;

    Count(T , n);

    return n;

}


/**********

【题目】试编写算法,求一棵以孩子兄弟链表表示的树的度。

孩子兄弟链表类型定义:

typedef struct CSTNode {

  TElemType  data;

  struct CSTNode  *firstChild, *nextSibling;

} CSTNode, *CSTree;

**********/

 

int Degree(CSTree T) /* 求树T的度*/

{  

   int ds,dt,d;

   CSTree p;

   if(!T) return 0;

   else { ds=0;dt=0;

       for( p = T->firstChild; p ; p= p->nextSibling){

          dt++;

          d= Degree(p);

          if(d>ds) ds =d;

       }

           

       return ds>dt?ds:dt;

   }

 

}

 

 

/**********

【题目】试编写算法,对以双亲表示法存储的树计算深度。

typedef struct {

  TElemType data;

  int     parent;  // 双亲位置

} PTNode; // 结点类型

typedef struct {

  PTNode nodes[MAX_TREE_SIZE]; // 结点存储空间

  int  n, r; // 结点数和根的位置

} PTree;

**********/

int PTreeDepth(PTree T) /* 求树T的深度*/

{

 int maxdep = 0,i,dep,j;

 for(i=0; i<T.n;i++){

      dep=0;

      for(j =i; j>0; j=T.nodes[j].parent) dep++;

      if(dep>maxdep) maxdep = dep;

 }

  return maxdep+1;

   

}

 

 

/**********

【题目】试编写算法,对以双亲孩子表示法存储的树计算深度。

孩子链表类型定义:

typedef struct ChildNode {  // 孩子结点

  int childIndex;

  struct ChildNode *nextChild;

} ChildNode; // 孩子结点类型

typedef struct  {

  TElemType data;

  int     parent;  // 双亲位置

  struct ChildNode *firstChild; // 孩子链表头指针

} PCTreeNode; // 结点类型

typedef struct {

  PCTreeNode *nodes; // 结点存储空间

  int  n, r; // 结点数和根的位置

} PCTree;

**********/

 

 int fun(PCTree T, int pos)

{

   if(T.nodes[pos].firstChild == NULL)  return 1;   

   ChildNode *temp = T.nodes[pos].firstChild;

   int depth = 1, max = 1;

   

   while(temp != NULL)

   {

      if( T.nodes[temp->childIndex].firstChild != NULL)

      {

        depth = fun(T, temp->childIndex);

        if(depth > max)

        max = depth;

      }

      temp = temp->nextChild;

   }

   

   return max + 1;       

                  

}

int PCTreeDepth(PCTree T) /* 求树T的深度*/

{

    int depth;

   depth = fun(T, T.r);

   return depth;

}

 

 

/**********

【题目】试编写算法,对以孩子-兄弟链表表示的树计算深度。

孩子兄弟链表类型定义:

typedef struct CSTNode {

  TElemType  data;

  struct CSTNode  *firstChild, *nextSibling;

} CSTNode, *CSTree;

**********/

int TreeDepth(CSTree T)

/* 求树T的深度*/

{

     int dep1,dep2,dep;

     if(!T) dep=0;

     else{

        dep1 =   TreeDepth(T->firstChild);

        dep2 = TreeDepth(T->nextSibling);

        dep = dep1+1>dep2?dep1+1:dep2;

     }

     return dep;

}

 

 

/**********

【题目】已知一棵树的由根至叶子结点按层次输出的

结点序列及每个结点的度。试编写算法,构造此树的

孩子兄弟链表。

孩子兄弟链表类型定义:

typedef struct CSTNode {

  TElemType  data;

  struct CSTNode  *firstChild, *nextSibling;

} CSTNode, *CSTree;

**********/

CSTree CreateCSTNode(char e) {

    CSTNode *p = NULL;

    p = (CSTNode*)malloc(sizeof(CSTNode));

    p->data = e;

    p->firstChild = NULL;

    p->nextSibling = NULL;

    return p;

}

 

 

void BuildCSTree(CSTree &T, char *node, int *degree)

/* 由结点的层序序列node和各结点的度degree构造树的孩子兄弟链表T */

{

    int i, j, present=1;

    CSTree Tree[50];

    

    if(NULL == node) {

        return;

    }   

    Tree[0] = CreateCSTNode(node[0]);

    T = Tree[0];

    for(i=0; node[i]!='\0'; i++) {

        if(degree[i]!=0) {

            Tree[present] = CreateCSTNode(node[present]);

            Tree[i]->firstChild = Tree[present];

            present ++;

            for(j=2; j<=degree[i]; j++) {

                Tree[present] = CreateCSTNode(node[present]);

                Tree[present-1]->nextSibling = Tree[present];

                present ++;

            }

        }

    }

}

 

 

/**********

【题目】试编写非递归算法,实现并查集带路径压缩的

查找操作。

并查集的类型定义如下:

typedef struct {

  int *parent;

  int  n;

} MFSet;

**********/

int find(MFSet S, int i)

/* 并查集带路径压缩的查找的非递归实现 */

{   if(i<0||i>=S.n) return -1;

    if(S.parent[i]<0) return i;

    S.parent[i] = find(S,S.parent[i]);

     return S.parent[i];

}

 

 

/**********

【题目】编写算法,创建有向图的邻接数组存储结构。

图的邻接数组存储结构的类型定义如下:

#define UNVISITED  0

#define VISITED    1  

#define MAX_VEX_NUM  4

#define INFINITY MAXINT // 计算机允许的整数最大值,即∞

typedef int VRType;

typedef char InfoType;

typedef char VexType;

typedef enum {DG,DN,UDG,UDN} GraphKind; // 有向图,有向网,无向图,无向网

typedef struct {

    VRType adj; // 顶点关系类型。对无权图,用1()0()表示相邻否;

                // 对带权图,则为权值类型

    InfoType *info; // 该弧相关信息的指针(可无)

}ArcCell;//,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

typedef struct {

  ArcCell arcs[MAX_VEX_NUM][MAX_VEX_NUM]; // 关系数组

  VexType vexs[MAX_VEX_NUM]; // 顶点数组

  int n, e;   // 顶点数和边(弧)数

  GraphKind kind; // 图的类型

} MGraph; // 邻接数组类型

typedef struct {

  VexType v, w;

  int inf;

} ArcInfo;

可调用以下基本操作:

Status InitGraph(MGraph &G, GraphKind kind, int n);

  // 初始化含n个顶点空间的kind类的空图G

int LocateVex(MGraph G, VexType v); // 查找顶点v在图G中的位序

**********/

Status CreateDG(MGraph &G, VexType *vexs, int n,

                           ArcInfo *arcs, int e)

/* 创建含n个顶点和e条边的有向图Gvexs为顶点信息,arcs为边信息*/

{  int i,j,k;

    VexType v,w;

    if((OVERFLOW==InitGraph(G, G.kind, n))) return ERROR;

    G.n = n;G.e = e;

    for(i = 0; i<G.n; i++) G.vexs[i] = vexs[i];

    for(k = 0; k<G.e; k++){

      v = arcs[k].v; w = arcs[k].w;

      i = LocateVex(G, v); j = LocateVex(G, w);

      if(i<0 || j<0) return ERROR;

     G.arcs[i][j].adj = 1;   

    }

    return OK;

}

 

/**********

【题目】编写算法,在图G中,相对于k顶点的当前

邻接顶点m顶点,求下一个邻接顶点。

图的邻接数组存储结构的类型定义如下:

#define UNVISITED  0

#define VISITED    1  

#define MAX_VEX_NUM  4

#define INFINITY MAXINT // 计算机允许的整数最大值,即∞

typedef int VRType;

typedef char InfoType;

typedef char VexType;

typedef enum {DG,DN,UDG,UDN} GraphKind; // 有向图,有向网,无向图,无向网

typedef struct {

    VRType adj; // 顶点关系类型。对无权图,用1()0()表示相邻否;

                // 对带权图,则为权值类型

    InfoType *info; // 该弧相关信息的指针(可无)

}ArcCell;//,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

typedef struct {

  ArcCell arcs[MAX_VEX_NUM][MAX_VEX_NUM]; // 关系数组

  VexType vexs[MAX_VEX_NUM]; // 顶点数组

  int n, e;   // 顶点数和边(弧)数

  GraphKind kind; // 图的类型

} MGraph; // 邻接数组类型

**********/

int NextAdjVex(MGraph G, int k, int m)

/* 在图G中,相对于k顶点的当前邻接顶点m顶点,求下一个邻接顶点*/

{

   int i;

   if(k==0&&m==0) return 0;  

    for( i = m+1; i<G.n; i++)//+1

        if(G.arcs[k][i].adj) return i;

    if(i == (G.n-1)) return -1;

    return -1;

}

 

/**********

【题目】编写算法,在图G中置顶点v到顶点w的弧或边。

图的邻接数组存储结构的类型定义如下:

#define UNVISITED  0

#define VISITED    1  

#define MAX_VEX_NUM  4

#define INFINITY MAXINT // 计算机允许的整数最大值,即∞

typedef int VRType;

typedef char InfoType;

typedef char VexType;

typedef enum {DG,DN,UDG,UDN} GraphKind; // 有向图,有向网,无向图,无向网

typedef struct {

    VRType adj; // 顶点关系类型。对无权图,用1()0()表示相邻否;

                // 对带权图,则为权值类型

    InfoType *info; // 该弧相关信息的指针(可无)

}ArcCell;//,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

typedef struct {

  ArcCell arcs[MAX_VEX_NUM][MAX_VEX_NUM]; // 关系数组

  VexType vexs[MAX_VEX_NUM]; // 顶点数组

  int n, e;   // 顶点数和边(弧)数

  GraphKind kind; // 图的类型

} MGraph; // 邻接数组类型

可调用以下基本操作:

int LocateVex(MGraph G, VexType v); // 查找顶点v在图G中的位序

**********/

Status SetArc(MGraph &G, VexType v, VexType w, ArcCell info)

/* 在图G中置顶点v到顶点w的弧或边*/

{

    int i,j;

      i = LocateVex(G,v);

      j = LocateVex(G,w);

      if(i < 0 || j < 0 || i == j)  return ERROR;

      if(G.arcs[i][j].adj == 1) return TRUE;

      else{       

        G.arcs[i][j].info = info.info;                

         G.arcs[i][j].adj = 1;

         G.e += 1;

         return TRUE;

      }

      return ERROR;

}

 

/**********

【题目】编写算法,计算以邻接表方式存储的有向图Gk顶点的出度。

图的邻接表存储结构的类型定义如下:

#define UNVISITED  0

#define VISITED    1  

#define INFINITY MAXINT // 计算机允许的整数最大值,即∞

typedef char VexType;

typedef enum {DG,DN,UDG,UDN} GraphKind; // 有向图,有向网,无向图,无向网

typedef struct AdjVexNode {

  int adjvex;  // 邻接顶点在顶点数组中的位序

  struct AdjVexNode *next; // 指向下一个邻接顶点(下一条边或弧)

  int info;    // 存储边(弧)相关信息,对于非带权图可不用

} AdjVexNode, *AdjVexNodeP; // 邻接链表的结点类型

typedef struct VexNode {

  VexType data;    // 顶点值,VexType是顶点类型,由用户定义

  struct AdjVexNode *firstArc; // 邻接链表的头指针

} VexNode; // 顶点数组的元素类型

typedef struct {

  VexNode *vexs;  // 顶点数组,用于存储顶点信息

  int n, e;       // 顶点数和边(弧)数

  GraphKind kind; // 图的类型

  int *tags;      // 标志数组

} ALGraph;  // 邻接表类型

**********/

int outDegree(ALGraph G, int k)

/* 求有向图Gk顶点的出度。若k顶点不存在,则返回-1 */

{

    int i,j = 0;

 AdjVexNodeP p;

 if(k<0||k>=G.n)    return -1;

 if(G.vexs[k].firstArc != NULL)

    p = G.vexs[k].firstArc;

 for( ; p!=NULL;p = p->next)

   {

     j++;

   }    

   return j;

 

}

 

/**********

【题目】编写算法,计算以邻接表方式存储的有向图G

k顶点的入度。

图的邻接表存储结构的类型定义如下:

#define UNVISITED  0

#define VISITED    1  

#define INFINITY MAXINT // 计算机允许的整数最大值,即∞

typedef char VexType;

typedef enum {DG,DN,UDG,UDN} GraphKind; // 有向图,有向网,无向图,无向网

typedef struct AdjVexNode {

  int adjvex;  // 邻接顶点在顶点数组中的位序

  struct AdjVexNode *next; // 指向下一个邻接顶点(下一条边或弧)

  int info;    // 存储边(弧)相关信息,对于非带权图可不用

} AdjVexNode, *AdjVexNodeP; // 邻接链表的结点类型

typedef struct VexNode {

  VexType data;    // 顶点值,VexType是顶点类型,由用户定义

  struct AdjVexNode *firstArc; // 邻接链表的头指针

} VexNode; // 顶点数组的元素类型

typedef struct {

  VexNode *vexs;  // 顶点数组,用于存储顶点信息

  int n, e;       // 顶点数和边(弧)数

  GraphKind kind; // 图的类型

  int *tags;      // 标志数组

} ALGraph;  // 邻接表类型

**********/

int inDegree(ALGraph G, int k)

/* 求有向图Gk顶点的入度。若k顶点不存在,则返回-1 */

{

    int i ,j;

  AdjVexNodeP p;

  if(k<0||k>=G.n)  return -1;

  for(i = 0,j=0;i<G.n;i++)

  {

   if(G.vexs[i].firstArc != NULL)

   {

       p = G.vexs[i].firstArc;

       for( ; p!=NULL;p = p->next)

         if(p->adjvex == k)

             j++;   

   }

  }

  return j;

}

 

/**********

【题目】编写算法,创建有向图的邻接表存储结构。

图的邻接表存储结构的类型定义如下:

#define UNVISITED  0

#define VISITED    1  

#define MAX_VEX_NUM  4

#define INFINITY MAXINT // 计算机允许的整数最大值,即∞

typedef char VexType;

typedef enum {DG,DN,UDG,UDN} GraphKind; // 有向图,有向网,无向图,无向网

typedef struct AdjVexNode {

  int adjvex;  // 邻接顶点在顶点数组中的位序

  struct AdjVexNode *next; // 指向下一个邻接顶点(下一条边或弧)

  int info;    // 存储边(弧)相关信息,对于非带权图可不用

} AdjVexNode, *AdjVexNodeP; // 邻接链表的结点类型

typedef struct VexNode {

  VexType data;    // 顶点值,VexType是顶点类型,由用户定义

  struct AdjVexNode *firstArc; // 邻接链表的头指针

} VexNode; // 顶点数组的元素类型

typedef struct {

  VexNode vexs[MAX_VEX_NUM];  // 顶点数组,用于存储顶点信息

  int n, e;       // 顶点数和边(弧)数

  GraphKind kind; // 图的类型

  int *tags;      // 标志数组

} ALGraph;  // 邻接表类型

 

可调用以下基本操作:

int LocateVex(ALGraph G, VexType v); // 查找顶点v在图G中的位序

**********/

Status CreateDG(ALGraph &G, VexType *vexs, int n,

                            ArcInfo *arcs, int e)

/* 创建含n个顶点和e条边的有向图Gvexs为顶点信息,arcs为边信息*/

{

    int i,j,k;

   VexType v,w;

   AdjVexNodeP p;

   G.n = n; G.e = e;

  // G.vexs = (VexNode*)malloc(sizeof(VexNode)*n);  

   G.tags = (int*)malloc(sizeof(int)*n);

   for(i = 0;i<G.n;i++)

    {

      G.tags[i] = UNVISITED;

      G.vexs[i].data = vexs[i];

      G.vexs[i].firstArc = NULL;

    }

   for(k = 0;k<G.e;k++)

   {

     v = arcs[k].v;  w=arcs[k].w;

     i = LocateVex(G,v);    j = LocateVex(G,w);

     if(i<0||j<0) return ERROR;

     

     p = (AdjVexNode*)malloc(sizeof(AdjVexNode));

     if(NULL == p)  return ERROR;

     p->adjvex = j;

     p->next = G.vexs[i].firstArc;

     G.vexs[i].firstArc = p;

            

   }

}

 

/**********

【题目】编写算法,创建无向图的邻接表存储结构。

图的邻接表存储结构的类型定义如下:

#define UNVISITED  0

#define VISITED    1  

#define MAX_VEX_NUM  4

#define INFINITY MAXINT // 计算机允许的整数最大值,即∞

typedef char VexType;

typedef enum {DG,DN,UDG,UDN} GraphKind; // 有向图,有向网,无向图,无向网

typedef struct AdjVexNode {

  int adjvex;  // 邻接顶点在顶点数组中的位序

  struct AdjVexNode *next; // 指向下一个邻接顶点(下一条边或弧)

  int info;    // 存储边(弧)相关信息,对于非带权图可不用

} AdjVexNode, *AdjVexNodeP; // 邻接链表的结点类型

typedef struct VexNode {

  VexType data;    // 顶点值,VexType是顶点类型,由用户定义

  struct AdjVexNode *firstArc; // 邻接链表的头指针

} VexNode; // 顶点数组的元素类型

typedef struct {

  VexNode vexs[MAX_VEX_NUM]; //*vexs; 顶点数组,用于存储顶点信息

  int n, e;       // 顶点数和边(弧)数

  GraphKind kind; // 图的类型

  int *tags;      // 标志数组

} ALGraph;  // 邻接表类型

 

可调用以下基本操作:

int LocateVex(ALGraph G, VexType v); // 查找顶点v在图G中的位序

**********/

Status CreateUDG(ALGraph &G, VexType *vexs, int n,

                            ArcInfo *arcs, int e)

/* 创建含n个顶点和e条边的无向图Gvexs为顶点信息,arcs为边信息*/

{

   int i,j,k;

   VexType v,w;

   AdjVexNodeP p,q;

   G.n = n; G.e = e;

  // G.vexs = (VexNode*)malloc(sizeof(VexNode)*n);  

   G.tags = (int*)malloc(sizeof(int)*n);

   for(i = 0;i<G.n;i++)

    {

      G.tags[i] = UNVISITED;

      G.vexs[i].data = vexs[i];

      G.vexs[i].firstArc = NULL;

    }

   for(k = 0;k<G.e;k++)

   {

     v = arcs[k].v;  w=arcs[k].w;

     i = LocateVex(G,v);    j = LocateVex(G,w);

     if(i<0||j<0) return ERROR;

     p = (AdjVexNode*)malloc(sizeof(AdjVexNode));

     if(NULL == p)  return ERROR;

     p->adjvex = j;

     p->next = G.vexs[i].firstArc;

     G.vexs[i].firstArc = p;

   

     

      q = (AdjVexNode*)malloc(sizeof(AdjVexNode));

     if(NULL == q)  return ERROR;

     q->adjvex = i;

     q->next = G.vexs[j].firstArc;

     G.vexs[j].firstArc = q;

   }

}

1 0