题一
![](https://pic.downk.cc/item/5ecb2fc8c2a9a83be5db8cda.jpg)
int combine(int A[],int &a,int B[],int b) //因为合并后a改变了长度,所以使用引用型&
{
//先写溢出情况(假设返回-1)
if(a+b>maxSize)
return -1;
//写成功合并的方法
int i=a,j=b;
while(j>0)
{
if(i==0||A[i-1]<B[j-1]) //从最后一个元素向前比较
{
A[j+i-1]=B[j-1]; //将B[]较大的元素先定位到A[]里,此时B[j-1]为第i+j大的元素
--j;
}
else
{
A[j+i-1]=A[i-1]; //此时A[i-1]为第i+j大的元素
--i;
}
}
a=a+b;
return a;
}
题二
![](https://pic.downk.cc/item/5ecb33f3c2a9a83be5e18688.jpg)
int compare(int A[],int a,int B[],int b)
{
int i=0,j=0; //指针作用
//相同部分
while(i<a&&j<b&&A[i++]=B[j++])
--i;
--j;
if(i==a&&j==b)
return 0;
if(i==a&&j!=b)
return -1;
if(i!=a&&j==b)
return 1;
if(A[i]>B[j])
return 1;
else
return -1; //A[i]<B[i]
}
题三
![](https://pic.downk.cc/item/5ecb38e7c2a9a83be5e99175.jpg)
int Combine(int lists[][maxSize],int lens[],int m)
{
int flag;
for(int i=1;i<m;i++)
{ //调用题一写过的combine方法
flag=combine(lists[0],lens[0],lists[i],lens[i]); //lens[i]为i行表的长度
if(flag==-1) //失败
break;
}
return flag; //成功
}
题四
![](https://pic.downk.cc/item/5ecb3bb7c2a9a83be5ee1720.jpg)
//递增,A∩B=C; 时间复杂度0(a+b),a、b为顺序表长度(元素个数)
int intersect(int A[],int a,int B[],int b,int C[],int &c)
{
//溢出情况
if(a+b>maxSize)
return -1;
int i=a,j=b,k; //从最后一个元素向前比较
while(i>=0&&j>=0)
{
if(A[i]>B[j])
--i;
if(A[i]<B[j])
--j;
else //A[i]=B[j]就要并入C[]
{
C[k++]=A[i];
--i;
--j;
}
}
c=k;
return c;
}
题五
![](https://pic.downk.cc/item/5ecb43c2c2a9a83be5fa97e7.jpg)
//非递减,A∪B=C;
//难点在于对重复元素的处理
int union(int A[],int a,int B[],int b,int C[],int &c)
{
int i=0,j=0,k=0;
//溢出情况
if(a+b>maxSize) //maxSize(已定义)应是数组C长度
return -1;
while(i<a&&j<b)
{
if(A[i]<B[j])
{ //注意k=0的判断,因为A、B可能是空表
//注意k>0的判断,C[k-1]溢出
if(k>0)
{
if(C[k-1]!=A[i]) //过滤相同元素
C[k++]=A[i++];
else
++i;
}
else
C[k++]=A[i++];
}
else
{
if(k>0)
{
if(C[k-1]!=B[j]) //过滤相同元素
C[k++]=B[j++];
else
++j;
}
else
C[k++]=B[j++];
}
}
while(i<a)
{
if(k>0)
{
if(C[k-1]!=A[i])
C[k++]=A[i++];
else
++i;
}
else
C[k++]=A[i++];
}
while(j<b)
{
if(k>0)
{
if(C[k-1]!=C[j])
C[k++]=B[j++];
else
++j;
}
else
C[k++]=B[j++];
}
c=k;
return c;
}
题六
![](https://pic.downk.cc/item/5ecc7fd7c2a9a83be5996f06.jpg)
void reverse(LinkNode *&h)
{
//该单链表没有头结点,h直接指向首节点
//逆转之后,h指向尾结点,使其成为首节点
//空的情况
if(h==NULL)
return;
LinkNode *p=h->next,*q=NULL;
while(p!=NULL)
{
h->next=q; //逆转h指针
//指针前移
q=h;
h=p;
p=p>next;
}
h->next=q;
}
题七
![](https://pic.downk.cc/item/5ecc8181c2a9a83be59bb874.jpg)
void separate(LinkNode *&A,LinkNode *&B,LinkNode *&C)
{
//假设A为初始单链表,分离后,A(数字)、B(字母)、C(其他)
LinkNode *pa,*pb,*pc,*p=A->next;
//pa,pb,pc分别是3个结果链表的链尾指针,初始时指向各表头
pa=A;
pb=B=(LinkNode *)malloc(sizeof(LinkNode));
pc=C=(LinkNode *)malloc(sizeof(LinkNode));
while(p!=NULL)
{
//此处书上运用了ctype.h函数库,人生苦短,能简就简
if(isdigit(p->data)) //数字字符,链入数字链
//if(p->data>='0'&&p->data<='9')
{
pa->next=p;
pa=p;
}
else if(isalpha(p->data)) //字母字符,链入字母链
//if((p->data>='a'&&p->data<='z')||(p->data>='A'&&p->data<='Z'))
{
pb->next=p;
pb=p;
}
else //其他字符,链入其他链
{
pc->next=p;
pc=p;
}
p=p->next;
}
pa->next=NULL;
pb->next=NULL;
pc->next=NULL; //尾域置空
}
题八
![](https://pic.downk.cc/item/5ecdd67bc2a9a83be51e36ba.jpg)
void insert(int S[],int &m,int L[],int R[],int n,int i,int j,int x) //m随插入元素而改变
{
//溢出情况
if(R[n]==m)
return;
else
{
int p=L[i]+j; //确定S[]中的插入位置p
int k;
for(k=m-1;k>=p;--k) //将p及以后元素全部后移一位
S[k+1]=S[k];
S[k+1]=x; //插入元素
++m; //所有表总长度+1
//将线性表范围标记L[]、R[]做修改
++R[i];
for(k=i+1;k<=n;++k)
{
++L[k];
++R[k];
}
}
}
void delete(int S[],int &m,int L[],int R[],int n,int i,int j)
{
int p=L[i]+j-1; //确定S[]中的删除位置p
int k;
for(k=p;k<m-1;++k) //将p及以后元素全部前移一位
S[k]=S[k+1];
--m; //所有表总长度-1
//将线性表范围标记L[]、R[]做修改
--R[i];
for(k=i+1;k<=n;++k)
{
--L[k];
--R[k];
}
}
题九
![](https://pic.downk.cc/item/5ecf1932c2a9a83be5ac551e.jpg)
//对顺序表先整体逆转,然后子表分别逆转
void reverse(int A[],int L,int R)
{
int i=L,j=R;
while(i<j)
{
int temp=A[i];
A[i]=A[j];
A[j]=temp;
++i;
--j;
}
}
void exchange(int A[],int m,int n)
{
//数组A[m+n],0~m-1存子表a,m~m+n-1存子表b,交换子表位置
reverse(A,0,m+n-1); //(bn,bn-1,...,am,am-1,..,a1)
reverse(A,0,n-1); //(b1,b2,...,bn,am,am-1,..,a1)
reverse(A,n,m+n-1); //(b1,b2,...,bn,a1,a2,...,am)
}
题十
![](https://pic.downk.cc/item/5ecf1f44c2a9a83be5b175d1.jpg)
void move(int A[],int n)
{
int p=0;
for(int i=0,i<n;i++)
{
if(A[i]!=0)
{
if(i!=p) //前移非0元素
{
A[p]=A[i];
A[i]=0;
}
++p;
}
}
}
题十一
![](https://pic.downk.cc/item/5ecf202ac2a9a83be5b279d3.jpg)
//(1)求链表中最大整数
int getMax(LinkNode *L)
{
//非空,仅一个元素
if(L->next==NULL)
return L->data;
int temp=getMax(L->next); //递归求最大值
if(L->data>temp)
return L->data;
else
return temp;
}
//(2)求链表的结点个数
int getNum(LinkNode *L)
{
//非空,仅一个元素
if(L->next==NULL)
return 1;
return 1+getNum(L->next); //递归求个数
}
//(3)求所有整数平均值
float getAvg(LinkNode *L,int n)
{
//非空,仅一个元素
if(L->next==NULL)
return (float)(L->data);
else
{
float sum=getAvg(L->next,n-1)*(n-1); //求后面n-1个元素和
return (float)(L->data+sum)/n; //加上首节点求平均值
}
}
题十二
![](https://pic.downk.cc/item/5ecf234ac2a9a83be5b6cb09.jpg)
//同李春葆数据结构课后习题16,并没完全看懂他的解答,这里深层分析一下
//①正向搜索寻找满足要求的结点
//②把该结点从链中摘下
//③反向根据访问计数寻找插入位置
//④把该结点重新插入到链表
DLinkNode *locate(DLinkNode *&DL,int x)
{
DLinkNode *p=DL->next,*q;
while(p!=NULL&&p->data!=x)
p=p->next;
if(p!=NULL)
{
//结点访问频度+1
++(p->freg);
q=p;
//从链表摘下这个结点
q->prior->next=q->next;
q->next->prior=q->prior;
//寻找重新插入位置
p=q->prior;
while(p!=DL&&q->freq>p->freq)
p=p->prior;
//插在p后
q->next=p->next;
q->prior=p;
p->next->prior=q;
p->next=q;
return q;
}
else
return NULL; //没找到
}