C++程序员面试指南第11章

第11章 排序
面试题1:编码实现直接插入排序
#include<iostream.h>
void main(void)
{
int ARRAY[10] = {0,6,3,2,7,5,4,9,1,8};


int i,j;
for(i = 0; i < 10 ; i++)  //将ARRAY[2],...,ARRAY[n]依次按序插入
{
cout<<ARRAY[i]<<" ";
}


cout<<endl;


for(i = 2; i <= 10; i++)
{
if(ARRAY[i] < ARRAY[i-1])  //如果ARRAY[i]大于一切有序 数值
{                          //ARRAY[i]将保持原序不动
ARRAY[0] = ARRAY[i];   //将ARRAY[0]看作是哨兵,是ARRAY[i]的副本
j = i-1;  
do                    //从右向左在有序区ARRAY[1.. i-1]中
{                       //查找ARRAY[i]的插入位置     
ARRAY[j+1] = ARRAY[j];  //将数值大于ARRAY[i]的记录后移
j--;
}
while(ARRAY[0] < ARRAY[j]);
ARRAY[j+1] = ARRAY[0];   //ARRAY[i]插入到正确的位置上
}
}
for(i = 0; i < 10; i++)
{
cout<<ARRAY[i]<<" ";
}
cout<<endl;
}


运行结果:
0 6 3 2 7 5 4 9 1 8
8 1 2 3 4 5 6 7 8 9


面试题2:编码实现希尔(Shell)排序


#include<stdio.h>
#define LEN 8
void main(void)
{
int d = LEN;
int R[LEN] = {76,81,60,22,98,33,12,79};  //待序数组


int i,j,t=1,temp;
while(d > 0)
{
d /= 2;
if( d > 0)
for(int y = 0; y < d; y++)
{
for( i = (d + y); i < LEN; i = (i + d))
{
if(R[i] < R[i-d])
{
temp = R[i];
j = i-d;
do{
printf("%d -> %d,",R[j],R[j+d]);
R[j+d] = R[j];


j = j - d;
}while(j >= 0 && temp < R[j]);
printf("%d -> %d ",temp,R[j+d]);
R[j+d] = temp;
}
}
printf("\n");
for(int a = 0; a < LEN; a++)
{
printf(" %d ",R[a]);
}
printf(" %d \n",y+1);
printf("\n");
}
printf("\n");
}
}


运行结果:
 76  81  60  22  98  33  12  79  1


81 -> 33,33 -> 81
 76  33  60  22  98  81  12  79  2


60 -> 12,12 -> 60
 76  33  12  22  98  81  60  79  3




 76  33  12  22  98  81  60  79  4




76 -> 12,12 -> 76 98 -> 60,76 -> 98,60 -> 76
 12  33  60  22  76  81  98  79  1


33 -> 22,22 -> 33 81 -> 79,79 -> 81
 12  22  60  33  76  79  98  81  2




60 -> 33,33 -> 60 98 -> 81,81 -> 98
 12  22  33  60  76  79  81  98  1


面试题3:编码实现冒泡排序


#include<stdio.h>
#define LEN 10    //数组长度
void main(void)
{
int ARRAY[10] = {0,6,3,2,7,5,4,9,1,8};  //待排序数组
printf("\n");
for(int a = 0; a < LEN; a++)
{
printf(" %d ",ARRAY[a] );     //打印数组内容
}
int i = 0;
int j = 0;
bool isChange;    //设定交换标志
for( i = 1; i < LEN; i++)
{                           //最多做LEN-1趟排序
isChange = 0;           //本趟排序开始前,交换标志应为假
for(j = LEN-1; j >= i; j--)  //对当前无序区ARRAY[i..LEN]
{
if(ARRAY[j+1] < ARRAY[j])
{                  //交换记录
ARRAY[0] = ARRAY[j+1];  //ARRAY[0]不是哨兵,仅做暂存单元
ARRAY[j+1] = ARRAY[j];
ARRAY[j] = ARRAY[0];
isChange = 1;    //发生了交换,故将交换标志置为1
}
}
printf("\n");
for(a = 0; a < LEN; a++)   //打印本次排序后数组内容
{
printf(" %d ",ARRAY[a]);
}
if(!isChange)     //本趟排序未发生交换,提前终止算法
{
break;
}
}
printf("\n");
return;
}


运行结果:
 0  6  3  2  7  5  4  9  1  8
 1  1  6  3  2  7  5  4  9  8
 2  1  2  6  3  4  7  5  8  9
 3  1  2  3  6  4  5  7  8  9
 4  1  2  3  4  6  5  7  8  9
 5  1  2  3  4  5  6  7  8  9
 5  1  2  3  4  5  6  7  8  9


面试题4:编码实现快速排序
#include<stdio.h>
#define LEN 9
void quikSort(int a[],int left,int right)
{
int i,j,temp;
i = left;
j = right;
temp = a[left];
if(left > right)
{
return;
}
while(i != j)
{
while( a[j] >= temp && j > i)
{
j--;
}
if(j > i)      //将大值放于后面
{
printf("\n");
a[i++] = a[j];
for(int m = 0; m < LEN; m++)
{
printf("%3d",a[m]);   //打印本次排序结果
}
}


while(a[i] <= temp && j > i)
{
i++;
}
if(j > i)
{
a[j--] = a[i];
printf("\n");
for(int m = 0; m < LEN; m++)
{
printf("%3d",a[m]);   //打印本次排序结果
}
}
}
a[i] = temp;
printf("\n");
for(int m = 0; m < LEN; m++)
{
printf("%3d",a[m]);
}
quikSort(a,left,i-1);
quikSort(a,i+1,right);
}
void main(void)
{
int a[9]={ 6,8,2,4,1,9,5,3,7}; //待排序数组
int i;
quikSort(a,0,9-1);  //快速排序


printf("\n"); 
for(i = 0; i < 9; i++)
{
printf("%3d",a[i]);
}
printf("\n");


}


运行结果:
  3  8  2  4  1  9  5  3  7
  3  8  2  4  1  9  5  8  7
  3  5  2  4  1  9  5  8  7
  3  5  2  4  1  9  9  8  7
  3  5  2  4  1  6  9  8  7
  1  5  2  4  1  6  9  8  7
  1  5  2  4  5  6  9  8  7
  1  2  2  4  5  6  9  8  7
  1  2  3  4  5  6  9  8  7
  1  2  3  4  5  6  9  8  7
  1  2  3  4  5  6  9  8  7
  1  2  3  4  5  6  9  8  7
  1  2  3  4  5  6  9  8  7
  1  2  3  4  5  6  7  8  7
  1  2  3  4  5  6  7  8  9
  1  2  3  4  5  6  7  8  9
  1  2  3  4  5  6  7  8  9
  1  2  3  4  5  6  7  8  9


面试题5:编码实现直接选择排序


#include<stdio.h>
#define LEN 9
void main(void)
{
int ARRAY[LEN]={5,6,8,2,4,1,9,3,7};  //待排序数组


printf("Before sorted:\n");  
for(int m = 0; m < LEN; m++)
{
printf("%d ",ARRAY[m]);
}
for(int i = 1; i <=LEN-1; i++)   //选择排序
{
int t = i-1;
int temp = 0;
for(int j = i; j < LEN; j++)
{
if(ARRAY[j] < ARRAY[t])
{
t = j;
}
}
if (t != (i-1))
{
temp = ARRAY[i - 1];
ARRAY[i-1] = ARRAY[t];
ARRAY[t] = temp;
}
}
printf("\n");
printf("After sorted:\n");
for(i = 0; i < LEN; i++)   //打印排序后数组
{
printf("%d ",ARRAY[i]);
}
printf("\n");
}


运行后结果:
Before sorted:
5 6 8 2 4 1 9 3 7
After sorted:
1 2 3 4 5 6 7 8 9


面试题6: 编码实现堆排序


#include<stdio.h>


void createHeep(int ARRAY[],int sPoint,int Len)  //生成大根堆
{
while((2*sPoint+1)<Len)
{
int mPoint=2*sPoint+1;
if((2*sPoint+2)<Len)
{
if(ARRAY[2*sPoint+1]<ARRAY[2*sPoint+2])
{
mPoint = 2*sPoint+2;
}
}
if(ARRAY[sPoint]<ARRAY[mPoint])  //堆被破坏,需要重新调整
{
int tmpData = ARRAY[sPoint]; //交换sPoint与mPoint的数据
ARRAY[sPoint] = ARRAY[mPoint];
ARRAY[mPoint] = tmpData;


sPoint = mPoint;
}
else
{
break;  //堆未破坏,不再需要调整
}
}
return;
}


void heepSort(int ARRAY[],int Len)  //堆排序
{
int i = 0;
for( i=(Len/2-1);i>=0;i--)   //将Hr[0,Length-1]建成大根堆
{
createHeep(ARRAY,i,Len);
}
for(i=Len-1;i>0;i--)
{
int tmpData = ARRAY[0];   //与最后一个记录交换
ARRAY[0] = ARRAY[i];
ARRAY[i] = tmpData;


createHeep(ARRAY,0,i);   //将H.r[0..i]重新调整为大根堆
}
return;
}


int main(void)
{
int ARRAY[]={5,4,7,3,9,1,6,8,2};  //待排序数组


printf("Before sorted:\n");     //打印排序前数组内容
for(int i = 0; i < 9; i++)
{
printf("%d ",ARRAY[i]);
}
printf("\n");


heepSort(ARRAY,9);         //堆排序


printf("After sorted:\n");  //打印排序后数组内容
for(i=0;i<9;i++)     
{
printf("%d ",ARRAY[i]);
}
printf("\n");
return 0;
}


运算结果:
Before sorted:
5 4 7 3 9 1 6 8 2
After sorted:
1 2 3 4 5 6 7 8 9




面试题7:编码实现基数排序
#include <stdio.h>
#include <malloc.h>
#define LEN 8
typedef struct node   //队列节点
{
int data;
struct node *next;
}node,*QueueNode;


typedef struct Queue     //队列
{
QueueNode front;
QueueNode rear;
}Queue,*QueueLink;


QueueLink CreateNullQueue(QueueLink &Q)  //创建空队列
{
Q = NULL;
Q = (QueueLink)malloc(sizeof(Queue));
if(NULL == Q)
{
printf("Fail to malloc null queue!\n");
return NULL;
}
Q->front = (QueueNode)malloc(sizeof(node));
Q->rear = (QueueNode)malloc(sizeof(node));
if(NULL == Q->front || NULL == Q->rear)
{
printf("Fail to malloc a new queue's front or rear!\n");
return NULL;
}
Q->rear = NULL;
Q->front->next = Q->rear;


return Q;
}
int lenData(node data[],int len)   //计算队列中各节点的数据的最大位数
{
int m = 0;
int temp = 0;
int d;
for(int i = 0; i < len; i++)
{
d=data[i].data;
while(d > 0)
{
d /= 10;
temp++;
}
if(temp > m)
{
m = temp;
}
temp = 0;
}
return m;
}
QueueLink Push(QueueLink &Q,node node)  //将数据压入队列
{
QueueNode p1,p;
p = (QueueNode)malloc(sizeof(node));
if(NULL == p)
{
printf("Fail to malloc a new node!\n");
return NULL;
}
p1 = Q->front;
while(p1->next !=NULL)
{
p1 = p1->next;
}
p->data = node.data;
p1->next = p;
p->next = Q->rear;
return NULL;
}
node Pop(QueueLink &Q)  //数据出队列
{
node temp;
temp.data = 0;
temp.next = NULL;
QueueNode p;
p = Q->front->next;
if(p != Q->rear)
{
temp = *p;
Q->front->next = p->next;
free(p);
p = NULL;
}
return temp;
}
int IsEmpty(QueueLink Q)
{
if(Q->front->next == Q->rear)
{
return 0;
}
return 1;
}
int main(void)
{
int i = 0;
int Max = 0;
int d = 10;
int power = 1;
int k = 0;
node Array[LEN] = {{450,NULL},{32,NULL},{781,NULL},{57,NULL},
{145,NULL},{613,NULL},{401,NULL},{594,NULL}};   //队列节点数


QueueLink Queue[10];
for(i = 0; i < 10; i++)
{
CreateNullQueue(Queue[i]);  //初始化队列数组
}
for(i = 0; i < LEN; i++)
{
printf("%d ",Array[i].data);
}
printf("\n");


Max = lenData(Array,LEN); //计算数组中关键字的最大位数
printf("Max= %d 位数\n",Max);


for(int j = 0; j < Max; j++)  //按位排序
{
if(j ==0) power = 1;
else power = power*d;


for(i = 0; i < LEN; i++)
{
k=Array[i].data/power-(Array[i].data/(power*d))*d;
Push(Queue[k],Array[i]);
}


for(int l=0,k=0; l<d; l++) //排序后出队列重入数组
{
while(IsEmpty(Queue[l]))
{
Array[k++] = Pop(Queue[l]);
}
}
for(int t = 0;t < LEN; t++)
{
printf("%d ",Array[t].data);
}
printf("\n");
}
return 0;
}


运行结果:
450 32 781 57 145 613 401 594
Max= 3 位数
450 781 401 32 613 594 145 57
401 613 32 145 450 57 781 594
32 57 145 401 450 594 613 781

猜你喜欢

转载自blog.csdn.net/juluwangriyue/article/details/53862761