C++课本的练习题及答案(第五章)

2022-11-29 17:07:04 浏览数 (1)

第五章练习题

一、选择题

1.语句  cout<<(1&2)<<","<<(1&&2)<<endl;  的输出结果是(    )。

(A)0, 0   (B)0, 1        (C)1, 0               (D)1, 1

2.语句  cout<<(1|2)<<","<<(1||2)<<endl;  的输出结果是(    )。

(A)0, 0   (B)1, 1        (C)2, 0               (D)3, 1

3.语句  cout<<(3<<3)<<endl; 的输出结果是(    )。

(A)24     (B)12          (C)9                   (D)6

4.语句  cout<<(24>>3)<<endl; 的输出结果是(    )。

(A)12     (B)9            (C)6                   (D)3

5.语句  cout<<(2^5)<<endl; 的输出结果是(    )。

(A)1             (B)3            (C)7                   (D)10

【解答】       B    D    A    D    C

二、程序练习

使用按位异或(^)运算,可以不需要中间变量,快速交换两个变量的值。设计一个函数,实现快速交换两个长度相同整型数组元素的值。

【解答】

voidSwap(int * Aary, int * Bary , int n)

{

      for(int i=0; i<n; i )

      {

             Aary[i]=Aary[i]^Bary[i];

             Bary[i]=Aary[i]^Bary[i];

             Aary[i]=Aary[i]^Bary[i];

      }

}

一、选择题

设有

unsigned A, B;             //表示两个集合

unsigned x;                   //表示集合元素

1.实现集合运算AB运算的对应表达式是(    )。

(A)A|B    (B)A&B (C)A&(~(A&B))   (D)A|B==B

2.实现集合运算A&B运算的对应表达式是(    )。

(A)A|B    (B)A&B (C)A&(~(A&B))   (D)A|B==B

3.实现集合运算A-B运算的对应表达式是(    )。

(A)A|B    (B)A&B (C)A&(~(A&B))   (D)A|B==B

4.实现集合运算AB运算的对应表达式是(    )。

(A)A|B    (B)A&B (C)A&(~(A&B))   (D)A|B==B

5.实现集合运算求补集~A运算的对应表达式是(    )。

(A)~A     (B)A==0     (C)A&(~(A&B))   (D)1<<(x-1)&A==1<<(x-1)

6.判断元素xA对应的表达式是(    )。

(A)~A     (B)A==0     (C)A&(~(A&B))   (D)1<<(x-1)&A==1<<(x-1)

【解答】              A      B       C       D      D

二、程序练习

设计一个函数:

int count( unsigned S );

计算由无符号整数S表示的集合中包含的元素个数。

【解答】

int count(unsigned S )

       unsigned bitMask = 1<<31, t=0;

       for(unsigned c=1; c<=32; c )

       {

              if(S&bitMask) 

                     t ;

              S<<=1;

       }

       return t;

}

一、选择题

1.有以下说明语句,则对应正确的赋值语句是(    )。

structpoint

{int x; int y; }p;

(A)point.x = 1; point.y = 2;         (B)point={ 1, 2 };

(C)p.x = 1; p.y = 2;                          (D)p = { 1, 2 };

2.已知有职工情况结构变量emp定义如下,则对emp中的birth正确赋值方法是(    )。

struct Date

{  int year;

   intmonth;

   int day;

};

strnct Employee

{  char name[20];

   long  code;

   Datebirth

};

Employee emp;

(A)year=1980; month=5;  day=1;

(B)birth.year=1980;  birth.month=5;  birth.day=1;

(C)emp.year=1980;  emp.month=5; emp.day=1;

(D)emp.birth.year=1980;  emp.birth.month=5;  emp.birth.day=1;

3.有以下说明语句,则叙述正确的是(    )。

struct Point

{  int x;

   int y;

};

(A)正确的结构类型说明                        (B)正确的结构变量说明

(C)错误的原因是结构中成员类型相同      (D)无意义的说明

4.有以下说明语句,则下列错误的引用是(    )。

struct  Worker

{  int no;

char name[20];

};

Worker w, *p =&w;

(A)w.no         (B)p->no           (C)(*p).no          (D)*p.no

5.s1和s2是两个结构类型变量,若要使赋值s1=s2合法,则要求(    )。

(A)s1只接收s2中相同类型的数据成员                

(B)s1和s2中的数据成员个数相同

(C)s1和s2是同一结构类型的变量                             

(D)s1和s2是存储字节长度一样的变量

【解答】              C       D      A      D      C

二、程序练习

1.阅读程序,写出运行结果。

#include <iostream>

using namespace std;

struct Data

{  int n;

   doublescore;

};

int main()

{  Data a[3] = { 1001,87,1002,72,1003,90 }, *p =a;

   cout<< (p )->n << endl;

   cout<< (p )->n << endl;

   cout<< p->n << endl;

   cout<< (*p).n << endl;

}

【解答】

2.阅读程序,写出运行结果。

#include <iostream>

using namespace std;

struct Employee

{  char name[ 20 ];

   charsex;

};

void fun( Employee *p )

{  if( (*p).sex == 'm' )

     cout << (*p).name << endl;

}

int main()

{  Employee emp[5] = { "Liming", 'm',"Wangxiaoping", 'f', "Luwei", 'm' };

   int i;

   for(i=0; i<3; i )

      fun( emp i );

}

【解答】

3.编写程序,定义一个表示 ( x, y ) 坐标点的结构类型:

struct Point{ int x; inty; };

main函数输入两个坐标点的值。函数:

int Line(Point a, Pointb);

判断两点的连线是否为水平线、垂直线或斜线。

【解答】

#include<iostream>

#include <iomanip>

using namespace std;

struct Point

{

      int x;

      int y;

};

int Line(Point a, Point b)

{

      if(a.x==b.x) return 1;

      if(a.y==b.y) return 2;

      return 0;

}

int main()

{

      Point a,b;

      cout<<"输入第一点坐标值:n";

      cout<<"x =";  cin>>a.x;

      cout<<"y =";  cin>>a.y;

      cout<<"输入第二点坐标值:n";

      cout<<"x =";  cin>>b.x;

      cout<<"y =";  cin>>b.y;

      int t=Line(a,b);

      if(t==1)

             cout<<"这是一条水平线n";

      else

             if(t==2)

                 cout<<"这是一条垂直线n";

             else

                     cout<<"这是一条斜线n";

}

一、选择题

1.有以下说明语句,则正确的赋值语句是(    )。

struct Point

{  double x;

   double y;

};

Point pp[3];

(A)pp[0]={0,0}                           (B)pp.x= pp.y=1;      

(C)pp[2]->x= pp[2]->y=2;          (D)pp[3].x=3;     pp[3].y=3

2.有以下说明语句,则引用形式错误的是(    )。

struct Student

{  int num;

   doublescore;

};

Studentstu[3]={{1001,80}, {1002,75}, {1003,91}}, *p=stu;

(A)p->num           (B)(p ).num            (C)(p )->num        (D)(*p).num

【解答】 D      B

二、程序练习

1.阅读程序,写出运行结果。

#include <iostream>

using namespace std;

struct Node

{  char * s;

   Node *q;

};

int main()

{  Node a[ ] = { { "Mary", a 1 }, {"Jack", a 2 }, { "Jim", a } };

   Node*p = a;

   cout<< p->s << endl;

   cout<< p->q->s<< endl;

   cout<< p->q->q->s << endl;

   cout<< p->q->q->q->s << endl;

}

【解答】

2.编写程序,定义点结构类型:

struct Point{ int x; inty; };

从键盘输入若干个点的数据,存放在结构数组中。函数:

int Line(Point ary[], intn);

判断这些点是否在一条水平线或垂直线上。

【解答】

#include<iostream>

#include <iomanip>

using namespace std;

struct Point

{

      int x;

      int y;

};

int Line(Point ary[], int n)

      int i, t1=0, t2=0;

      for( i=0; i<n-1; i )

      {

             t1 =ary[i].x==ary[i 1].x;

             t2 =ary[i].y==ary[i 1].y;

      }

      if(t1==n-1) return 1;

      if(t2==n-1) return 2;

      return 0;

}

int main()

{

      const int N=3;

      Point ary[N];

      for(int i=0; i<N; i )

      {

             cout<<"输入第"<<i 1<<"点坐标值:n";

             cout<<"x =";  cin>>ary[i].x;

             cout<<"y =";  cin>>ary[i].y;

      }

      int t=Line(ary, N);

      if(t==1)

             cout<<"构成一条水平线n";

      else

             if(t==2)

                 cout<<"构成一条垂直线n";

             else

                     cout<<"不能构成水平线或垂直线n";

}

一、选择题

有说明语句:

Struct Node{ int data;Node * next; };

Node *head, *p,*q, *s;

并且,head是单向链表的头指针,p指向链表中的节点,q指向*p的前驱节点。

1.在*p之后插入节点*s的操作是(    )。

(A)p->next=s;  s->next=p->next;             (B)s->next=p-next; p->next=s;

(C)p =s->next; s =p->next;              (D)s =p->next; p =s->next;

2.在*p之前插入节点*s的操作是(    )。

(A)q =s->next; s =p->next;              (B)q->next=s;  s->next=p;

(C)s=p->next;  q=s->next;                (D)s->next=p;  q->next=s;

3.在*hear之前插入节点*s的操作是(    )。

(A)s->next=head; head=s;                (B)s->next=head->next;  head->next=s;

(C)head=s; s->next=head;                (D)head->next=s; s->next=head->next;

4.删除*p节点的操作是(    )。

(A)q = p; delete p;                             (B)p = q; delete q;

(C)q->next=p->next; delete p;                   (D)p->next = q->next; delete q;

5.删除*(head->next)的操作是(    )。

(A)p=head->next; head->next=head->next->next; delete p;

(B)head->next=head->next->next; p=head->next; delete p;

(C)p=head; head=head->next; delete p;

(D)head=head->next; p=head; delete p;

【解答】 B       D      A      C       A

二、程序练习

有以下声明语句和主函数。其中Create函数从键盘输入整数序列,以输入0为结束,按输入逆序建立一个以head为表头的单向链表。程序在main函数调用Create建立链表,调用ShowList函数验证链表。例如,输入序列为1 2 3 4 5 0,建立的链表是5 4 3 2 1。补充程序中的Create函数和ShowList函数。

#include<iostream>

using namespace std;

struct Node{int data;Node * next;};

void Create(Node*&head);

void ShowList(Node*head);

void main()

{  Node *head=new Node;

   head=NULL;

   cout<<"输入链表元素,以输入 0 结束:n";

   Create(head);

   cout<<"输出逆向链表n";

   ShowList(head);    

}

【解答】

void Create(Node *&head)

{

      Node *p;

      p = new Node ;

      cin>>p->data;

      while(p->data!=0)

      {

             if(head==NULL)

                    { head=p;head->next=NULL; }

             else

                    {

                           p->next= head;

                           head =p;

                    }

      p=new Node;

      cin>>p->data;

      }

}

void ShowList(Node *head)

{

      cout << "now theitems of node are: n";

      while( head )

      {

             cout <<head->data << 't';

             head = head->next;

      }

      cout << endl;

}

综合练习
一、思考题

1.判断一个整数n的奇偶性,可以利用位运算吗?请你试一试。

【解答】

可以。一个整数当最低位为1时,它是奇数,否则为偶数。以下函数返回对参数k的奇偶判断。

bool odd( int k )

{

  return 1&k;

}

2.长度为N的数组可以表示N个元素的集合,若有 S[i]==1,表示对应元素在集合中,如何实现集合的基本运算?请你试一试。并从内存和处理要求上与5.2.2节中集合的实现方法进行比较。

【解答】

长度为N的数组S可以表示有N个元素的集合。当S[i]==1,表示元素i 1在集合中;当S[i]==0,表示元素i 1不在集合中。集合运算通过对数组元素操作完成。

用数组实现集合,每一个数组元素只能表示一个集合元素,运算的空间和时间消耗高于用无符号整数和位运算实现集合运算。

用数组实现集合运算程序如下。

#include<iostream>

using namespacestd;

void setPut(unsigned *S );                                    //输入集合S的元素

void setDisplay(const unsigned *S );                //输出集合S中的全部元素

bool putX(unsigned *S, unsigned x );               //元素x并入集合

void Com(  unsigned *C, const unsigned *A, constunsigned *B);     //求并集C=A∪B

void setInt(  unsigned *C, const unsigned A, const unsignedB);       //求交集C=A∩B

void setDif(const unsigned A, const unsigned B );                           //求差集C=A-B

bool Inc( constunsigned *A, const unsigned *B );                           //判蕴含

bool In( constunsigned *S,  const unsigned x );                            //判属于x∈S

bool Null( constunsigned *S );                                             //判空集

const int N=32;

//输入集合元素

voidsetPut(unsigned *S)

{ unsigned x;

  cin >> x;

  while( x>0&&x<=N)

  {  putX(S, x );       //把输入元素并入集合S

     cin>> x;

  }

}

//输出集合S中的全部元素

void setDisplay(const unsigned *S )

{ cout <<"{ ";

  if (Null(S))

  cout<<"  }n";

  else

  {  for(int i=0; i<N; i )       //输出元素

         {

           if( S[i] )                          

                cout << i 1 <<", ";

         }

     cout<< "bb }n";                  //擦除最后的逗号

  }

  return;

}

//元素x并入集合S

bool putX(unsigned *S, unsigned x )

{if(x>0&&x<=N)

  { S[x-1] = 1;

    return true;

  }

  return false;

}

//求并集C=A∪B

void Com(  unsigned *C, const unsigned *A, constunsigned *B )

{ for( int i=0; i<N;i )

    C[i]=int( A[i] || B[i] ) ;

}

//求交集C=A∩B

void setInt(unsigned *C, const unsigned *A, const unsigned *B )

{ for( int i=0;i<N; i )

    C[i]=int( A[i]&&B[i] ) ;

}

//求差集C=A-B

void setDif(  unsigned *C, const unsigned *A, constunsigned *B )

{ for( int i=0;i<N; i )

    C[i]=int( A[i]&&!(A[1]&&B[i]) ) ;

}

//判蕴含,A蕴含于B时返回true

bool Inc( constunsigned *A, const unsigned *B )

{ for(int i=0;i<N; i )

   { if(A[i]&&!B[i])

     return false;

   }

  return true;

}

//判属于,x∈S时返回true

bool In( constunsigned *S, const unsigned x )

{  return S[x-1];

}

//判空集,S为空集时返回true

bool Null( constunsigned *S )

{ for( int i=0;i<N; i )

  { if( S[i])

    return false;

  }

  return true;

}

int main()

{ unsignedA[N]={0}, B[N]={0},  C[N]={0};

  unsigned x;

  cout << "Input the elements of setA, 1-"<<N<<", until input 0 :n";

  setPut( A );

  cout << "Input the elements of setB, 1-"<<N<<", until input 0 :n";

  setPut( B );

  cout<<"A = ";

  setDisplay( A );

  cout<<"B = ";

  setDisplay( B );

  cout << "Input x: ";

  cin>>x;

  cout << "Put " << x<< " in A = ";

  putX( A, x) ;

  setDisplay(A);

  cout << "C = A B = ";

  Com( C, A, B );

  setDisplay( C );

  cout << "C = A*B = ";

  setInt( C, A, B );

  setDisplay( C );

  cout << "C = A-B = ";

  setDif( C, A, B );

  setDisplay( C );

  if( Inc( A, B ) )

    cout<< "A <= B is truen";

  else

    cout<< "not A <= Bn";

  cout << "Input x: ";

  cin >> x;

  if( In( A, x ) )

    cout<< x << " in An";

  else

    cout<< x << " not in An";

}

3.分析以下说明结构的语句:

struct Node

{  int data;

   Nodeerror;                      //错误

   Node *ok;                       //正确

};

error和ok分别属于什么数据类型?有什么存储要求?error出错的原因是什么?

【解答】

error是Node结构类型数据成员,错误。原因是结构定义的数据成员若为本身的结构类型,是一种无穷递归。ok是指向Node类型的指针,定义正确,占4字节。

4.例5-15中用辅助数组对结构数组进行关键字排序,有定义:

person *index[100];

index数组存放结构数组元素的地址。如果把index定义改为:

int index[100];

用于存放结构数组元素的下标,可以实现对结构数组的索引排序吗?如何修改程序?请你试一试。

  【解答】

可以。关键是通过整型索引数组元素作为下标访问结构数组。表示为:

all[pi[i]].name    all[pi[i]].id           all[pi[i]].salary

有关程序如下:

#include<iostream>

usingnamespace std;

structperson                //说明结构类型

{

charname[10];

  unsigned int id; 

  double salary;

};

voidInput( person[], const int );

voidSort( person[], int[],const int );

voidOutput( const person[], int[],const int );

intmain()

{

personallone[100] ;           //说明结构数组

  int index[100];                  //说明索引数组

  int total ;

  for(int i=0; i<100; i )      //索引数组元素值初始化为结构数组元素下标

       index[i]=i ;

  cout<<"输入职工人数:";

  cin>>total;

  cout<<"输入职工信息:n";

  Input(allone,total);

  cout<<"以工资做关键字排序n";

  Sort(allone,index, total);

  cout<<"输出排序后信息:n";

  Output(allone,index,total);

}

voidInput( person all[], const int n )

{

inti ;  

  for( i=0; i<n; i )            // 输入数据

   {

cout<<i<<":姓名:";

     cin>>all[i].name;

     cout<<"编号:";

     cin >> all[i].id;

     cout<<"工资:";

     cin >> all[i].salary ;

   }

}

voidSort(person all[], int pi[], const int n)

{

 int i,j; 

  int t;                               //交换用中间变量

  for(i=1; i<n; i )                     //以成员salary做关键字排序

  {

for(j=0;j<=n-1-i; j )

    if(all[pi[j]].salary>all[pi[j 1]].salary)     //通过索引数组访问结构数组元素

       {

t=pi[j];                                         //交换索引数组元素值

pi[j]=pi[j 1];

pi[j 1]=t;

       }

  }

}

voidOutput(const person all[], int pi[], const int n)

{

 for( int i=0; i<n; i )             // 输出排序后数据

   cout<<all[pi[i]].name<<'t'<<all[pi[i]].id<<'t'<<all[pi[i]].salary<<endl;

}

5.有以下结构说明和遍历单向链表的函数。函数内有错误吗?是什么性质的错误?请上机验证你的分析。

struct Node

{  int data; 

   Node *next;

};

void ShowList( Node *head)

{  while( head )

   {  cout<< head->date << 'n';

      head ;

   }

}

【解答】

head 错误,原因是动态链表的结点存放不是连续顺序的内存空间,它们是逐个结点通过new建立的,所以不能用 做地址偏移运算。应该用:

head=head->next;

二、程序设计

1.编写程序,将一个整型变量右移4位,并以二进制数形式输出该整数在移位前和移位后的数值。观察系统填补空缺的数位情况。

【解答】

#include<iostream>

using namespacestd;

voidbitDisplay(unsigned value);

int main()

{

  unsigned x;

  cout << "Enter an unsigned integer:";

  cin >> x;

  bitDisplay(x);

  x>>=4;

  cout<<"Right 4-bitn";

  bitDisplay(x);

}

voidbitDisplay(unsigned value)

{

  unsigned c;

  unsigned bitmask = 1<<31;

  cout << value << " =t";

  for( c=1; c<=32; c )

  {

         cout << ( value&bitmask ? '1': '0' );

         value <<= 1;

         if( c%8 == 0 )

          cout << ' ';

  }

  cout << endl;

}

2.整数左移一位相当于将该数乘以2。编写一个函数:

unsigned power2( unsignednumber, unsigned pow );

使用移位运算计算number*2pow,并以整数形式输出计算结果。注意考虑数据的溢出。

【解答】

unsigned power2( unsigned number, unsigned pow )

{

  unsigned c=1;

  unsigned bitmask = 1<<31;   

  while(c<31)           //溢出判断

  {

         if( number&bitmask )break;           //查找最高位的1

         c ;

         bitmask>>=1;

  }

  if(pow<c)

         return number<<pow;

  else

  {

         cout<<"overflow!n";

         return 0;

  }

}

3.设计重载函数,使用按位异或(^)运算,实现快速交换两个整型变量和浮点型变量的值。

【解答】

void swap (int &a, int &b)

{

  a=a^b;

  b=a^b;

  a=a^b;

}

void swap(double &x,double &y)

  int*xp,*yp;

  xp = (int*)(&x);

  yp = (int*)(&y);

  *xp=(*xp)^*(yp);     *yp=(*xp)^(*yp);     *xp=(*xp)^(*yp);

  xp ;   yp ;

  *xp=(*xp)^*(yp);     *yp=(*xp)^(*yp);     *xp=(*xp)^(*yp);

}

4.设计函数,不使用辅助数组,实现两个int类型或double类型数组的数据快速交换。

【解答】

void Swap(char * Aary, char * Bary , int n)

{

  for(int i=0; i<n; i )

  {

         Aary[i]=Aary[i]^Bary[i];

         Bary[i]=Aary[i]^Bary[i];

         Aary[i]=Aary[i]^Bary[i];

  }

}

以上函数使用char*,字节指针做数组参数,对于不同类型的数组,调用函数时,只需要对实参地址做指针类型转换,并且设定参数n对应的实参是交换数据的总字节数。例如,交换double类型数组的数据可以有以下方式:

const int N=100;

double x[N];

double y[N];

//……

Swap((char*)x,(char*)y,sizeof(double)*N);

5.集合的元素通常是字符。设计程序,用无符号整数表示ASCII码字符集合,用位运算实现各种基本集合运算。

【解答】

ASCII码是0~127的整数,可以用长度为4的无符号整型数组表示集合,如教材例5-6所示。区别是,在输入集合元素时,需要把字符转换成整型数据,在输出操作中,把整型集合元素转换成字符型数据。

程序略。

6.使用结构类型表示复数。设计程序,输入两个复数,可以选择进行复数的+、-、×或÷运算,并输出结果。

【解答】

#include<iostream>

#include<iomanip>

usingnamespace std;

struct complex

{

 double re, im; 

};

int main()

{

    complex a,b,c;  char oper;

    cout << "输入复数a的实部和虚部: ";

    cin >> a.re >>a.im;

    cout << "输入复数b的实部和虚部:";

    cin >> b.re >>b.im;

    cout << "输入运算符: ";

    cin >> oper;

    switch ( oper )

   {

           case ' ':  c.re=a.re b.re; c.im=a.im b.im;

                         break;

           case '-':   c.re=a.re-b.re; c.im=a.im-b.im;

                         break;

           case '*':   c.re=a.re*b.re-a.im*b.im;

                         c.im=a.im*b.re a.re*b.im;

                         break;

           case '/':   c.re=(a.re*b.re a.im*b.im)/(b.re*b.re b.im*b.im);

                         c.im=(a.im*b.re-a.re*b.im)/(b.re*b.re b.im*b.im);

                         break;

       default:             cout<< "input error!" << endl;

                         return 0;

}

cout << "c=" << c.re;

cout << setiosflags( ios::showpos );

cout << c.im << "i" << endl;

return 0;

}

7.把一个班的学生姓名和成绩存放到一个结构数组中,寻找并输出最高分者。

【解答】

#include <iostream>

using namespace std;

struct data

{

  char name[12];

  double score;

};

double searchMax(data *a, int n );

int main()

{

      data stu[ ] = {"李小平",90,"何文章",66,"刘大安",87,"汪立新",93,"罗建国",78,

             "陆丰收",81,"杨勇",85,"吴一兵",55,"伍晓笑",68,"张虹虹",93};

      double max;

      int n=sizeof(stu) /sizeof(data);

      max=searchMax(stu, n);

      for( int i=0; i<n; i )

             if( stu[i].score ==max )

                    cout<<stu[i].name <<'t'<< stu[i].score<<endl;

}

double searchMax(data *a, int n )

{

      int i;

      double max=a[0].score;

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

        if( a[i].score > max ) max = a[i].score;

      return max;

}

8.使用结构表示X-Y平面直角坐标系上的点,编写程序,顺序读入一个四边形的4个顶点坐标,判别由这个顶点的连线构成的图形是否为正方形、矩形或其他四边形。要求:定义求两个点距离的函数使用结构参数。

【解答】

#include<iostream>

#include<cmath>

usingnamespace std;

struct point

{

 double x;

 double y;

};

double d( point p1, point p2 )

{

 return sqrt( pow( p1.x-p2.x,2 ) pow( p1.y-p2.y,2 ) );

}

int main()

{

 int i;  point p[5];

  for( i=1; i<=4; i )

   { cout << "输入第"<< i << "个顶点的横坐标和纵坐标:";

     cin >> p[i].x >> p[i].y; 

}

  if( fabs( d( p[1],p[2] ) - d( p[3],p[4] ))<=1e-8

       && fabs( d( p[1],p[4] ) - d( p[2],p[3] ))<=1e-8

       && fabs( d( p[1],p[3] ) - d( p[2],p[4] ))<=1e-8)

    if( fabs( d( p[1],p[2] ) - d( p[2],p[3] ))<1e-8 )

        cout << "四个顶点构成的图形为正方形!"<< endl;

    else cout << "四个顶点构成的图形为矩形!"<< endl;

 else cout << "四个顶点构成的图形为其它四边形!"<< endl;

}

9.建立一个结点包括职工的编号、年龄和性别的单向链表,分别定义函数完成以下功能:

(1)遍历该链表输出全部职工信息;

(2)分别统计男、女职工的人数;

(3)在链表尾部插入新职工结点;

(4)删除指定编号的职工结点;

(5)删除年龄在60岁以上的男性职工或55岁以上的女性职工结点,并保存在另一个链表中。

要求:用主函数建立简单菜单选择,并测试程序。

【解答】

#include<iostream>

usingnamespace std;

struct employee

{

int num;

 int age;

 char sex;

 employee *next;

};

employee *head, *head1;

//建立单向链表

employee *create()

{

 employee *head, *p, *pend;

 char ch;

 head = NULL;

 cout << "t输入数据?(y/n)";cin >> ch;

 if( ch == 'y' )

  {

 p= new employee;

    cout << "t编号:";  cin >> p->num;

    cout << "t年龄:";  cin >> p->age;

    cout << "t性别:";  cin >> p->sex;

}

 else

    goto L0;

 while( ch == 'y' )

  {

 if( head == NULL ) head = p;

    else pend->next = p;

    pend = p;

      cout << "t输入数据?(y/n)"; cin>>ch;

    if( ch == 'y' )

      {

 p= new employee;

         cout << "t编号:"; cin >> p->num;

         cout << "t年龄:"; cin >> p->age;

         cout << "t性别:"; cin >> p->sex;  

}

  }

 pend->next = NULL;

 L0: return head;         

}

//显示单向链表中全部职工信息

void show( employee *head )

{

 employee *p = head;

if( !head ) { cout << "t空链表!" << endl; goto L1; }

    cout << "t链表中的数据是:n";

 while( p )

  {

 cout << 't' << p->num <<"," << p->age << "," << p->sex<< endl;

      p = p->next; 

}

L1:

}

//统计男女职工人数

void count( employee *head )

{

 employee *p = head;

 int m, f;

  m= 0; f = 0;

 while( p )

  {

 if( p->sex == 'm' )

m ;

     else

 f ;

     p = p->next; 

}

 cout << "t男职工人数:"<< m << endl;

 cout << "t女职工人数:"<< f << endl;

}

//在链表尾部插入新结点

 employee *insert()

{

employee *pend = head, *p;

 //在空链表尾部插入新结点

 if( !head )

  {

p = new employee;

   cout << "t编号:";  cin >> p->num;

   cout << "t年龄:";  cin >> p->age;

   cout << "t性别:";  cin >> p->sex;

   head = p;

   p->next = NULL;

   return head;

}

 //在链表尾部插入新结点

 while( pend->next != NULL )

  {

pend = pend->next; 

}

  p= new employee;

 cout << "t编号:";  cin >> p->num;

 cout << "t年龄:";  cin >> p->age;

 cout << "t性别:";  cin >> p->sex;

 pend->next = p;

 pend = p;

 pend->next = NULL;

 return head;

}

//删除指定编号的结点

employee *del( int bh )

{

employee *p, *q;

 if ( !head )

  {

cout << "t空链表!" << endl;

   goto L2; 

}

 //删除链首结点

 if( head->num == bh )

  {

 p= head;

    head = head->next;

      delete p;

      cout << "t结点已被删除!" << endl;

      goto L2;

}

 //删除非链首结点

  q= head;

 while( q->next != NULL )

  {

if ( q->next->num == bh )

   {

 p= q->next;      //待删除结点

        q->next = p->next;

        delete p;

      cout << "t结点已被删除!"<< endl;

        goto L2;  

}

     q = q->next;

  }

 cout << "t找不到需删除结点!"<< endl;

L2: return ( head );

}

//删除指定年龄段的结点,并把被删除结点保存在另一链表中

employee *delcreate()

{

 employee *p, *pd, *p1, *q;

 int flag;

 //建立新链表

 if ( head == NULL )

  {

 cout << "t空链表!" << endl;

    goto L3;

}

 head1 = NULL;

 pd = new employee;

  p= head;

 flag = 0;

 while ( p != NULL )

  {

if( p->age >= 55 &&p->age <=60 )

     {

 pd->num = p->num;

       pd->age = p->age;

       pd->sex = p->sex;

       if( head1 == NULL )

head1 = pd;

     else

p1->next = pd;

     p1 = pd;

       pd = new employee;

       flag = 1; 

}

      p = p->next; 

}

if ( flag == 0 )

  {cout << "t没有需删除的结点!"<< endl; goto L3; }

p1->next = NULL;

//显示新链表

cout <<"t新链表中的数据是: n";

p = head1;

while( p )

 {

 cout << 't' << p->num <<"," << p->age << "," << p->sex<< endl;

  p = p->next;

}

//删除指定年龄的结点

p = head;

q = p;

while ( p != NULL )

{

 if( p->age >= 55 && p->age<= 60)

   if( head->age == p->age )

  {

pd = head;               //待删除结点

       head = head->next;

           deletepd;

           p= head;

           continue;

   }

     else

           if(p->next == NULL )

           {

 pd= p;                       //待删除结点        

             q->next = NULL;

       delete pd;

             goto L3; 

}

           else

           {

pd = p;                        //待删除结点

q->next = p->next;

delete pd;

p = q->next;

continue;

}

q = p;

p = p->next; 

}

 L3: return ( head );

}

int main()

{

int choice, bh ;

L:

cout << "ntt请键入操作选择n" << endl;

cout << "t 1 --- 建立单向链表" << endl;

    cout << "t 2 --- 显示单向链表中全部职工信息" << endl;

    cout << "t 3 --- 统计男女职工人数" << endl;

    cout << "t 4 --- 在职工尾部插入新结点" << endl;

    cout << "t 5 --- 删除指定编号的结点" << endl;

    cout << "t 6 --- 删除指定年龄的结点,并把被删除结点保存在另一链表中" << endl;

    cout << "t 0 --- 退出" << endl ;

cout << "tt";

    cin >> choice ;

 switch ( choice )

  {

case 1 : head = create() ; goto L ;

    case 2 : show( head );  goto L ;

    case 3 : count( head ); goto L;

    case 4 : head = insert(); goto L;

    case 5 : cout << "t输入需删除结点编号:";

                 cin >> bh;

                     head = del( bh ); goto L;

      case 6 : head = delcreate(); goto L;

      case 0 : cout << " t退出程序的运行!n" << endl ; break ;

    default : cout << "t输入错误,请重新输入!n" << endl ; goto L; 

}

}

10.输入一行字符,按输入字符的反序建立一个字符结点的单向链表,并输出该链表中的字符。

【解答】

#include<iostream>

usingnamespace std;

struct node

{

 char ch;

 node *next; 

};

void show( node *head );

int main()

{

 node *head, *p;

 char c;

 head = NULL;

 while( (c = getchar()) != 'n' )                //输入一行字符

  {

 p= new node;                              //建立新结点

      p->ch = c;

      p->next = head;                        //插入表头

      head=p; 

}

  show(head);

}

void show( node *head )                        //输出链表

{

 node *p = head;

 cout << "链表中的字符是:n";

 while( p )

  { cout << p->ch;

     p = p->next; 

}

 cout << endl;

}

11.设有说明语句:

struct List { intdata;  List * next; };

List *head;

head是有序单向链表的头指针。请编写函数:

void Count( List * head);

计算并输出链表数据相同值的结点及个数。例如,若数据序列为:

2 3 3 3 4 5 5 6 6 6 6 7 89 9

则输出结果为:

data   number

3                3

5                2

6                4

9                2

可以用例5-18的程序生成有序链表,测试Count函数。

【解答】略

12.用带头结点的有序单向链表可以存放集合,如图5.16所示。头结点不存放集合元素,仅为操作方便而设置。使用这种数据结构,设计集合的输入、输出和各种基本运算的函数。

图5.16  带头结点的有序单向链表

【解答】略

推荐阅读

全部习题章节: C 课本的练习题及答案(第四章) C 课本的练习题及答案(第五章) C 课本的练习题及答案(第六章) C 课本的练习题及答案(第七章) C 课本的练习题及答案(第八章)

0 人点赞