j=SelectMinKey(a,n,i);
if(i!
=j){
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
intmain(){
inta[100],n,i;
printf("请输入要进行排序的数的个数n:
\n");
scanf("%d",&n);
printf("请输入这n个数:
\n");
for(i=1;i<=n;i++)//注意数组的起始位置。
scanf("%d",&a[i]);
SelectSort(a,n);
printf("排序后的n个数是:
\n");
for(i=1;i<=n;i++)
printf("%4d",a[i]);
printf("\n");
system("pause");
}
数据测试:
7、堆排序
代码;
数据测试:
8、归并排序
代码:
//归并排序。
//时间复杂度:
O(nlogn)。
空间复杂度:
O(n)。
#include
#include
voidMerge(intSR[],intTR[],intn,inti,intm,intt){
//将有序的a[i..m]和a[m+1..t]合并为有序的TR[i..t]。
intj,k;
for(j=m+1,k=i;i<=m&&j<=t;k++){
if(SR[i]<=SR[j])TR[k]=SR[i++];
elseTR[k]=SR[j++];
}
if(i<=m)
while(i<=m)
TR[k++]=SR[i++];
if(j<=t)
while(j<=t)
TR[k++]=SR[j++];
}
voidMSort(intSR[],intTR[],intn,ints,intt){
//将SR[s..t]归并排序为TR[s..t]。
intm,TR1[100];
if(s==t)TR[s]=SR[s];
else{
m=(s+t)/2;
MSort(SR,TR1,n,s,m);//递归地将SR[s..m]归并为有序的TR1[s..m]。
MSort(SR,TR1,n,m+1,t);//递归地将SR[m+1..t]归并为有序的TR1[m+1..t]。
Merge(TR1,TR,n,s,m,t);//将TR1[s..m]、TR1[m+1..t]归并到TR1[s..t];
}
}
voidMergeSort(inta[],intn){
MSort(a,a,n,1,n);
}
intmain(){
inta[100],n,i;
printf("请输入要进行排序的数的个数n:
\n");
scanf("%d",&n);
printf("请输入这n个数:
\n");
for(i=1;i<=n;i++)//注意数组的起始位置。
scanf("%d",&a[i]);
MergeSort(a,n);
printf("排序后的n个数是:
\n");
for(i=1;i<=n;i++)
printf("%4d",a[i]);
printf("\n");
system("pause");
}
数据测试:
2、链表与数组
1、假定数组A[N]的n个元素中有多个零元素,编写算法将A中所有的非零元素依次移到A的前端。
【华中科技大学,06年】
代码:
#include
#include
intmain(){
inta[100],n,i;
while
(1){
printf("pleaseinputthenumberofthearray:
\n");
scanf("%d",&n);
printf("pleaseinputeveryvalueinthearray:
\n");
for(i=0;iscanf("%d",&a[i]);
intp=-1,q=0,m=0;
for(i=0;iif(a[i]==0){
if(!
q)p=i;//p记录第一个零元素的位置。
q++;//q记录已经遍历到的零元素的个数。
m++;
}
else{
if(p>0&&q>0){
a[p]=a[i];//移动非零元素至前面。
//a[i]=0;
q--;//零元素个数减1。
if(q>0)p++;
}
elseif(m>0)
a[i-m]=a[i];
}
printf("thevaluesafterremoving:
\n");
for(i=0;iprintf("%4d",a[i]);
printf("\n");
}
system("pause");
}
数据测试:
2、顺序存储的线性表,其数据元素为整型,试编写一算法,将A拆分成B和C两个表,使A中的元素值大于等于0的存入B,小于0的存入C中。
要求:
(1)表B和C另外设置存储空间。
(2)表B和C不另外设置,而利用A的空间。
(1)代码:
#include
#include
intmain(){
intA[10]={1,2,3,-4,-7,5,7,-9,8,-2};
intB[10],C[10];
inti,j,k;
i=j=k=0;
for(i=0;i<10;i++)
if(A[i]>=0)B[j++]=A[i];
elseC[k++]=A[i];
printf("拆分前:
\n");
printf("A:
");
for(i=0;i<10;i++)
printf("%4d",A[i]);
printf("\n");
printf("拆分后:
\n");
printf("B:
");
for(i=0;iprintf("%4d",B[i]);
printf("\n");
printf("C:
");
for(i=0;iprintf("%4d",C[i]);
printf("\n");
system("pause");
}
数据测试:
(2)代码:
#include
#include
intmain(){
intA[10]={1,2,3,-4,-7,5,7,-9,8,-2};
inti=0,j=9,temp,t=0;
printf("拆分前:
\n");
printf("A:
");
for(t=0;t<10;t++)
printf("%4d",A[t]);
printf("\n");
while(i<=j){
while(A[i]>=0)i++;
while(A[j]<0)j--;
if(itemp=A[i];
A[i]=A[j];
A[j]=temp;
}
}
printf("拆分后:
\n");
printf("B:
");
for(t=0;tprintf("%4d",A[t]);
printf("\n");
printf("C:
");
for(t=i;t<9;t++)
printf("%4d",A[t]);
printf("\n");
system("pause");
}
数据测试:
3、逆置单链表
无头节点单链表,节点:
数据域data、指针域next,表头指针h。
通过遍历链表,将所有的指针方向逆转,其中表头指针指向最后一个节点。
算法:
voidInverse(&h){
if(h==null)return;
p=h->next;
pr=null;
while(p){
h->next=pr;
pr=h;
h=p;
p=p->next;
}
}
4、删除顺序表中元素
长度为n的线性表A采用顺序存储方式,写算法删除线性表中所有值为item的数据元素。
要求:
时间复杂度为O(n),空间复杂度为O
(1)。
5、将数组偶数移至奇数之前
设计将数组A[n]中所有的偶数移到奇数之前的算法。
要求:
不增加存储空间,且时间复杂度为O(n)。
代码:
#include
#include
intmain(){
intA[20]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
inti,j,x;
//x=A[0];
i=0;
j=19;
while(ix=A[i];
while(A[j]%2==1)j--;
if(iA[i]=A[j];
i++;
}
if(iwhile(A[i]%2==0)i++;
if(iA[j]=A[i];
j--;
}
A[i]=x;
}
for(i=0;i<20;i++)
printf("%d",A[i]);
printf("\n");
system("pause");
}
数据测试:
6、逆序输出单链表各元素
代码:
#include
#include
typedefstructnode{
chardata;
structnode*next;
}list;
typedeflist*link;
linkCreate(){//创建链表。
charch;
list*p;
linkhead;
head=NULL;
ch=getchar();
while(ch!
='\n'){
p=(list*)malloc(sizeof(list));
p->data=ch;
p->next=head;
head=p;
ch=getchar();
}
returnhead;
}
voidDisplay(linkhead){
list*p;
p=head;
printf("头插法建立的链表的输出结果:
\n");
while(p){
printf("%c",p->data);
p=p->next;
}
printf("\n");
}
intmain(){
linkhead;
printf("请输入链表的内容:
\n");
head=Create();
Display(head);
system("pause");
}
数据测试:
7、合并两个单链表(Ⅰ)
A为递增有序的单链表,长度为n。
B为递减有序的单链表,长度为m。
编写程序,利用原表的存储空间,将A、B合并成为一个递增有序的单链表。
要求:
时间复杂度为O(m+n)。
算法:
//先将单链表B逆转:
voidReverse(Node*r){
Node*q=r,*p=null,*temp;
while(q){
temp=q;
q=q->next;
temp->next=p;
p=temp;
}
r=p;
}
//再合并两个非递减的单链表:
Node*Merge(Node*a,Node*b){
Node*s,*r;
Node*p=a,*q=b;
while(p!
=NULL&&q!
=NULL){
if(p->datadata){
if(p==a){
s=a;
r=a;
}
elser->next=p;
p=p->next;
}
else{
if(q==b){
s=b;
r=b;
}
elser->next=q;
q=q->next;
}
r=r->next;
}
if(p==NULL&&q!
=NULL)r->next=q;
if(q==NULL&&p!
=NULL)r->next=p;
returns;
}
//主方法。
合并题目所给的两个单链表。
Node*MergeFunc(Node*a,Node*b){
Reverse(b);
Node*result=Merge(a,b);
resultresult;
}
8、合并两个单链表(Ⅱ)
单链表A、B,数据都为整型有序,编写程序,利用原节点,将A和B中具有相同数据的节点删除,并将B中与原A表不同数据的节点插入A中,保持A的递增有序。
算法:
voidMerge(Node*a,Node*b){
Node*p,*q,*previous;
Node*temp1,*temp2;
//假设a、b带头节点。
p=a->next;
q=b->next;
previous=a;
while(p!
=NULL&&q!
=NULL){
if(p->datadata){
previous=p;//previous指示p的前驱。
p=p->next;
}
elseif(p->data==q->data){
temp1=p;
p=p->next;
previous->next=p->next;
deletetemp;
}
else{
temp2=q;
q=q->next;
previous->next=temp;
temp->next=p;
previous=previous->next;
}
}
if(p==NULL&&q!
=NULL)previous->next=q;
}
9、两个单链表求∩和∪
已知2个按元素非递减的单链表A和B,设计一算法利用原表节点空间形成连续的新链表A’和B’,使得A’=A∪B,B’=A∩B。
算法:
voidAdjust(LinkList&A,LinkList&B){
//假设A、B带头结点。
pa=A;
pb=B;
while(pa->next!
=NULL&&pb->next!
=NULL){
if(pa->next->datanext->data)
pa=pa->next;
elseif(pa->next->data==pb->next->data){
pa=pa->next;
pb=pb->next;
}
else{
temp=pb->next;
pb->ne