第五章练习题

一、选择题

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<< "\b\b }\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 true\n";

else

cout<< "not A <= B\n";

cout << "Input x: ";

cin >> x;

if( In( A, x ) )

cout<< x << " in A\n";

else

cout<< x << " not in A\n";

}

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-bit\n";

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 << "\n\t\t请键入操作选择\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 << "\t\t";

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++课本的练习题及答案(第八章)

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

  1. 《机器学习》周志华课后习题答案——第五章(1-7已完结)

    第五章课后习题答案 文章目录 第五章课后习题答案 一.试述将线性函数f(x) = wTx用作神经元激活函数的缺陷? 二.试述使用图5.2(b)激活函数的神经元与对率回归的联系 三.对于图5.7中的Vi ...

  2. 《C Primer Plus》中文第六版 编程练习答案 第五章 运算符、表达式和语句

    C Primer Plus 第5章 运算符.表达式和语句 编程练习答案 ***先说一下关于 i++和 ++i 情况.*** 1.编写一个程序,把用分钟表示的时间转换成用小时和分钟表示的时间.使用#de ...

  3. 云计算技术与应用课后答案第五章

    第五章 云桌面 1.下列描述中,属于云桌面优势的有: (ABC) A.工作桌面集中维护和部署,桌面服务能力和工作效率提高 B.业务数据远程隔离,有效保护数据安全 C.多终端多操作系统的接入,方便用户使 ...

  4. 微型计算机原理与接口技术 (周荷琴 冯焕清)第六版 课后习题答案 第五章(部分答案)

    第五章 3. 试从功耗.容量.价格优势.使用是否方便等几个方面,比较静态 RAM 和 动态 RAM 的优缺点,并说明这两类存储器芯片的典型应用 SRAM.DRAM 均为易失性存储器. 优点:SRAM  ...

  5. 《Java EE企业级应用开发教程(SSM)》练习题答案---第五章Spring的事务管理(仅供参考)

    单选题 1.以下有关事务管理方式相关说法错误的是(). A.Spring中的事务管理分为两种方式:一种是传统的编程式事务管理,另一种是声明式事务管理 B.编程式事务管理:是通过AOP技术实现的事务管理 ...

  6. C++练习题及答案(五)

    第8章练习题 同步练习8.1 1.一个大的应用程序,通常由多个类构成,类与类之间互相协同工作, 它们之间有三种主要关系.下列不属于类之间关系的是(    ). (A)gets-a            ...

  7. 计算机网络测试题第五章答案,计算机组成原理练习题答案第五章.doc

    1 .已知X 和Y ,试用它们的变形补码计算出X + Y ,并指出结果是否溢出. (1) X = 0 .11011 ,Y = 0 .11111 (2) X = 0 .11011 ,Y = - 0 .1 ...

  8. 面向对象程序设计c++版董正言张聪课本课后习题答案第五章

    5.6两个数相加 int add(int a, int b) {return a + b; } 5.7两个数相加 #include<iostream> using namespace st ...

  9. 计算机网络谢希仁第七版课后答案第五章 传输层

    5-01 试说明运输层在协议栈中的地位和作用,运输层的通信和网络层的通信有什么重要区别?为什么运输层是必不可少的? 答:运输层处于面向通信部分的最高层,同时也是用户功能中的最低层,向它上面的应用层提供 ...

最新文章

  1. 手把手教你如何扩展GridView之自带CheckBox
  2. git 回退版本并强制提交
  3. Delphi 多文件拖放获取路径示例
  4. [ 1001] 动态开辟二维数组的说明
  5. Linux下安装jdk1.6和tomcat
  6. 《Python Cookbook 3rd》笔记(4.6):带有外部状态的生成器函数
  7. java 用面向接口编程的方式开发打印机_Java“打印机”模型理解面向接口编程。实现接口定义类,接口实现类,核心“业务”类分离...
  8. 【SKILLS】About the phonetics
  9. 无法关闭microsoft word_仅记录word文档损坏后的挣扎(亲历)
  10. jdbc 数据源_Java数据源,JDBC数据源示例
  11. jsp乔丹AJ购物网站网上鞋店黑色ssh
  12. Linux忘记密码的找回方法
  13. java毕业设计宠物店管理系统设计与实现源码+系统+数据库+lw文档+调试运行
  14. MAC之U盘(制作U盘启动必须是在mac系统中)
  15. 戴德金--连续性和无理数--我自己做的中文翻译第5页
  16. FeignClient中每一个@RequestParam 都要设置value,否者报错
  17. 斐波那契(兔子)数列python
  18. android怎么调textview间距,Android如何设置TextView的行间距、行高。
  19. 【Java集合】Java集合一览(汇总)
  20. 记录一次 在linux 搭建的mysql迁移到docker容器中

热门文章

  1. 固态硬盘 每秒1.5G
  2. 火柴人生存挑战2html5游戏在线玩,火柴人生存挑战
  3. 小程序集-朋友圈集赞神器
  4. uniapp 网易云音乐app项目总结
  5. Teams会议/实时事件中的参会者报告详解
  6. shell一键安装lnmp
  7. 试用期离职,该如何解释?
  8. (Python语法篇)4.序列(3)字典
  9. 文本分类Keras RNN实践——应用腾讯和百度中文词向量
  10. C语言获取股票数据,c/c++开发分享获取贵州茅台2010年1月1号至今的股票交易数据,计算该股票历史数据的5日均线和30日均线...