数据结构与算法–第二章题解
食用建议
1.不要直接CTRL+C一波带走,要不可能会被老师一波带走;
2.可以手抄一边模板,会有奇效;
3.调调数据在本地跑一下也很有成就感,直接就理解了。
文章目录
- 数据结构与算法--第二章题解
- 食用建议
- ==模板== --顺序表
- ==模板==--单链表
- ==模板== --循环单链表
- 补充--单链表求最大值
- 补充--单链表删除最大值
- 补充--单链表逆置
- 补充--单链表二路归并
- 补充--二路归并
- 补充--奇数在前偶数在后
- 补充--求交集(有bug)
- 补充--有序第K小
- ==A01==:2.2 顺序表——删除最大值
- ==A02==:2.5 有序顺序表——删除重复元素
- ==A03==:〖NOIP2005P〗陶陶摘苹果
- ==A04==:整数顺序表的并集、差集和交集
- ==A05==:DNA排序
- ==A06==:垂直直方图
- ==A07==:两个整数相互交换
- ==A08==:2.1 顺序表——调整数据元素
- ==A09==:顺序表区间元素删除
- ==A10==:整数顺序表的基本运算
- ==A11==:单链表的基本运算
- ==A12==:单链表的插入和显示操作
- ==A13== 整数单链表的基本运算-1
- ==A14== 整数单链表的基本运算-2
- ==A15== 循环单链表的基本运算
模板 --顺序表
#define MaxSize 100
typedef int ElemType; //设置顺序表元素为int类型
typedef struct
{ ElemType data[MaxSize]; //存放顺序表的元素
int length; //顺序表的实际长度
} SqList; //顺序表类型声明
void InitList(SqList &L) //初始化顺序表L
{
L.length=0;
}
void DestroyList(SqList L) //销毁顺序表L
{
}
int GetLength(SqList L) //求长度
{
return L.length;
}
int GetElem(SqList L,int i,ElemType &e) //求第i个元素
{ if (i<1 || i>L.length) //无效的i值
return 0;
else
{ e=L.data[i-1];
return 1;
}
}
int Locate(SqList L,ElemType x) //查找第一个x元素的位置
{ int i=0;
while (i<L.length && L.data[i]!=x)
i++; //查找第1个值为x的元素
if (i>=L.length) return(0); //未找到返回0
else return(i+1); //找到后返回其逻辑序号
}
int InsElem(SqList &L,ElemType x,int i) //插入x作为第i个元素
{ int j;
if (i<1 || i>L.length+1) //无效的参数i
return 0;
for (j=L.length;j>i;j--) //将位置为i的元素及之后的元素后移
L.data[j]=L.data[j-1];
L.data[i-1]=x; //在位置i处放入x
L.length++; //顺序表长度增1
return 1;
}
int DelElem(SqList &L,int i) //删除第i个元素
{ int j;
if (i<1 || i>L.length) //无效的参数i
return 0;
for (j=i;j<L.length;j++) //将位置为i的元素之后的元素前移
L.data[j-1]=L.data[j];
L.length--; //顺序表长度减1
return 1;
}
void DispList(SqList L) //输出顺序表
{ int i;
for (i=0;i<L.length;i++)
printf("%d ",L.data[i]);
printf("\n");
}
void CreateList(SqList &L,ElemType a[],int n) //整体创建顺序表L
{
int i,k=0; //k累计顺序表L中的元素个数
for (i=0;i<n;i++)
{
L.data[k]=a[i]; //向L中添加一个元素
k++; //L中元素个数增1
}
L.length=k; //设置L的长度
}
void Deletex(SqList &L,ElemType x)
{ int i,k=0;
for (i=0;i<L.length;i++)
if (L.data[i]!=x) //将不为x的元素插入到L中
{ L.data[k]=L.data[i];
k++;
}
L.length=k; //重置L的长度
}
模板–单链表
#define ElemType char
struct node{ //定义链表
ElemType data;
node *next;
};
//头结点用head表示
void initList(node *&head){ //初始化函数
head=new node();//c语言:head=(node *)malloc(sizeof(node));
head->next=NULL;
//head->data =0;
}
void destoryList(node *&head){ //销毁链表
node *pre=head;
node *p=head->next; //从头结点开始删除
while(p!=NULL){
delete pre; //c语言:free(pre);
pre=p;
p=p->next;
}
delete pre;
}
int getLength(node *head){ //求长度
int count=0;
node *p=head->next;
while(p!=NULL){
p=p->next;
count++;
}
return count;
}
int findValue(node *head,ElemType value){ //找到值为value的结点
node *p=head->next;
int count=1;
while(p!=NULL&&p->data!=value)
{
p=p->next;
count++;
}
return count;
}
int GetElem(node *L, int i, ElemType &e)//查找第i个值
{ int j=0;
node *p=L; //p指向头结点,计数器j置为0
if (i<=0) return 0; //参数i错误返回0
while (p!=NULL && j<i)
{ j++;
p=p->next;
}
if (p==NULL) return 0; //未找到返回0
else
{ e=p->data;
return 1; //找到后返回1
}
}
int insElem(node *&head,ElemType value,int i){ //在第i个元素后插入值为value的结点
node *p=head->next;
int count=1;
if(i<0) return 0;
while(p!=NULL&&count!=i){ //查找第i-1个结点p
p=p->next;
count++;
}
if(p==NULL) return 0;
node *q=new node();
q->data=value;
q->next=p->next;
p->next=q;
return 1;
}
void deleElem(node *&head,int i){ //删除第i个元素
node *p=head;
int count=1;
while(p!=NULL&&count!=i){ //查找第i-1个结点
p=p->next;
count++;
}
node *q=p->next;
p->next=q->next;
delete q;
}
void output(node *head){ //输出
node *p=head->next;
while(p!=NULL){
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
void createList_tail(node *head,ElemType a[],int len){ //尾插法创建链表
node *tc=head;
for(int i=0;i<len;i++){
node *s=new node();
s->data=a[i];
tc->next=s;
tc=s;
}
tc->next=NULL;
}
模板 --循环单链表
void InitList(SLinkNode *&L) //L为引用型参数
{ L=(SLinkNode *)malloc(sizeof(SLinkNode));
L->next=L;//注意这里有变化
}
void DestroyList(SLinkNode *&L)
{ SLinkNode *pre=L,*p=pre->next;
while (p!=L) //注意
{ free(pre);
pre=p; p=p->next; //pre、p同步后移
}
free(pre);
}
int GetLength(SLinkNode *L)
{ int i=0;
SLinkNode *p=L->next;
while (p!=L) //注意不等于头节点
{ i++;
p=p->next;
}
return i;
}
int GetElem(SLinkNode *L,int i,ElemType &e)
{ int j=1;
SLinkNode *p=L->next; //p指向首结点,计数器j置为1
if (i<=0) return 0; //参数i错误返回0
while (p!=L && j<i) //找第i个结点p
{ j++;
p=p->next;
}
if (p==L) return 0; //未找到返回0
else
{ e=p->data;
return 1; //找到后返回1
}
}
int Locate(SLinkNode *L, ElemType x)
{ int i=1;
SLinkNode *p=L->next;
while (p!=L && p->data!=x)
//从第1个数据结点开始查找data域为x的结点
{
p=p->next;
i++;
}
if (p==L) return 0; //未找到值为x的结点返回0
else return i; //找到第一个值为x的结点返回其序号
}
int InsElem(SLinkNode *&L, ElemType x, int i) //插入结点算法
{ int j=1;
SLinkNode *pre=L,*p=pre->next,*s;
if (i<=0) return 0; //参数i错误返回0
while (p!=L && j<i) //查找第i个结点p和其前驱结点pre
{
j++;
pre=p; p=p->next; //pre、p同步后移一个结点
}
if (p==L && i>j+1) return 0;//参数i>n+1时错误返回0
else //成功查找到第i个结点的前驱结点pre
{ s=(SLinkNode *)malloc(sizeof(SLinkNode));
s->data=x; //创建新结点用于存放元素x
s->next=pre->next; //将s结点插入到pre结点之后
pre->next=s;
return 1; //插入运算成功,返回1
}
}
int DelElem(SLinkNode *&L,int i)
{ int j=0;
SLinkNode *p=L,*q;
if (i<=0) return 0; //参数i错误返回0
while (p->next!=L && j<i-1) //查找第i-1个结点p
{
j++;
p=p->next;
}
if (p->next==L) return 0; //未找到这样的结点返回0
else
{ q=p->next; //q指向被删结点
if (q==L) return 0; //没有第i个结点时返回0
else
{ p->next=q->next; //从单链表中删除q结点
free(q); //释放其空间
return 1; //成功删除返回1
}
}
}
void DispList(SLinkNode *L)
{ SLinkNode *p=L->next;
while (p!=L)
{ printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
补充–单链表求最大值
node *Maxnode(node *head)
{ node *p=head->next,*maxp=p;
while (p!=NULL) //遍历所有的结点
{ if (maxp->data<p->data)
maxp=p; //当p指向更大的结点时,将其赋给maxp
p=p->next; //p沿next域下移一个结点
}
return maxp;
}
补充–单链表删除最大值
void Delmaxnode(node *&head)
{ node *p=head->next,*pre=head,*maxp=p,*maxpre=pre;
while (p!=NULL)
{ if (maxp->data<p->data)
{ maxp=p;
maxpre=pre;
}
pre=p; //pre、p同步后移,保证pre始终为p的前驱结点
p=p->next;
}
maxpre->next=maxp->next; //删除maxp结点
delete maxp; //释放maxp结点//free(maxp);
}
补充–单链表逆置
void Reverse(node *&head)
{ node *p=head->next;
head->next=NULL;
while (p!=NULL) //遍历所有数据结点
{ node *q=p->next; //q临时保存p结点之后的结点
p->next=head->next; //将结点p插入到头结点之后
head->next=p;
p=q;
}
}
补充–单链表二路归并
void Merge(SLinkNode *ha, SLinkNode *hb,SLinkNode *&hc)
{ SLinkNode *pa=ha->next,*pb=hb->next,*tc;
hc=ha; tc=hc; //将ha的头结点用作hc的头结点
free(hb); //释放hb的头结点
while (pa!=NULL && pb!=NULL)
{ if (pa->data<pb->data)
{ tc->next=pa;tc=pa; //将pa链接到tc之后
pa=pa->next;
}
else //pa->data>pb->data
{ tc->next=pb;tc=pb; //将pb链接到tc之后
pb=pb->next;
}
}
tc->next=NULL;
if (pa!=NULL) tc->next=pa; //ha单链表还有结点时
if (pb!=NULL) tc->next=pb; //hb单链表还有结点时
}
补充–二路归并
void Merge(SqList A,SqList B,SqList &C) //C为引用型参数
{ int i=0,j=0,k=0; //k记录顺序表C中的元素个数
while (i<A.length && j<B.length)
{ if (A.data[i]<B.data[j])
{ C.data[k]=A.data[i];
i++;k++;
}
else //A.data[i]>B.data[j]
{ C.data[k]=B.data[j];
j++;k++;
}
}
while (i<A.length) //将A中剩余的元素复制到C中
{ C.data[k]=A.data[i];
i++;k++;
}
while (j<B.length) //将B中剩余的元素复制到C中
{ C.data[k]=B.data[j];
j++;k++;
}
C.length=k; //指定顺序表C的实际长度
}
补充–奇数在前偶数在后
void Move(SqList &L)
{ int i=0,j=L.length-1;
while (i<j)
{ while (L.data[i]%2==1) i++; //从前向后找偶数
while (L.data[j]%2==0) j--; //从后向前找奇数
if (i<j)
swap(L.data[i],L.data[j]); //交换这两元素
}
}
补充–求交集(有bug)
已知有两个递增有序顺序表A和B,设计一个算法由顺序表A和B的所有公共元素产生一个顺序表C。并分析该算法的空间复杂度和时间复杂度。
void Commelem(SqList A,SqList B,SqList &C)
{ int i=0,j=0,k=0; //k记录顺序表C中的元素个数
while (i<A.length && j<B.length)
{ if (A.data[i]<B.data[j])
i++;
else if (A.data[i]>B.data[j])
j++;
else //A.data[i]=B.data[j]
{ C.data[k]=A.data[i];
i++; j++; k++;
}
}
C.length=k; //指定顺序表C的实际长度
}
补充–有序第K小
有两个递增有序顺序表A和B,分别含有n和m个整数元素(最大的元素不超过32767),假设这n+m个元素均不相同。
int Topk1(SqList A,SqList B,int k,ElemType &e)
{ int i=0,j=0;
if (k<1 || k>A.length+B.length)
return 0; //参数错误返回0
while (i<A.length && j<B.length)
{ k--;
if (A.data[i]<B.data[j])
{ if (k==0)
{ e=A.data[i];
return 1;
}
i++;
}
else
{ if (k==0)
{ e=B.data[j];
return 1;
}
j++;
}
} //end while
if (i<A.length) //A没有扫描完毕
e=A.data[i+k-1];
else if (j<B.length) //B没有扫描完毕
e=B.data[j+k-1];
return 1;
}
#define INF 32767
int Topk2(SqList A,SqList B,int k,ElemType &e)
{ int i=0,j=0;
if (k<1 || k>A.length+B.length)
return 0; //参数错误返回0
while (true)
{ k--;
int x=(i<A.length?A.data[i]:INF);
int y=(j<B.length?B.data[j]:INF);
if (x<y)
{ if (k==0)
{ e=x;
return 1;
}
i++;
}
else
{ if (k==0)
{ e=y;
return 1;
}
j++;
}
}
}
A01:2.2 顺序表——删除最大值
有一个整数序列,采用顺序表L存储。设计尽可能高效的算法删除L中最大值的元素(假设这样的元素有多个)。
#include <stdio.h>
#include<iostream>
using namespace std;
#define MaxSize 100
typedef int ElemType; //设置顺序表元素为int类型
typedef struct
{ ElemType data[MaxSize]; //存放顺序表的元素
int length; //顺序表的实际长度
} SqList; //顺序表类型声明
void InitList(SqList &L) //初始化顺序表L
{
L.length=0;
}
void DestroyList(SqList L) //销毁顺序表L
{
}
int GetLength(SqList L) //求长度
{
return L.length;
}
int GetElem(SqList L,int i,ElemType &e) //求第i个元素
{ if (i<1 || i>L.length) //无效的i值
return 0;
else
{ e=L.data[i-1];
return 1;
}
}
int Locate(SqList L,ElemType x) //查找第一个x元素的位置
{ int i=0;
while (i<L.length && L.data[i]!=x)
i++; //查找第1个值为x的元素
if (i>=L.length) return(0); //未找到返回0
else return(i+1); //找到后返回其逻辑序号
}
int InsElem(SqList &L,ElemType x,int i) //插入x作为第i个元素
{ int j;
if (i<1 || i>L.length+1) //无效的参数i
return 0;
for (j=L.length;j>i;j--) //将位置为i的元素及之后的元素后移
L.data[j]=L.data[j-1];
L.data[i-1]=x; //在位置i处放入x
L.length++; //顺序表长度增1
return 1;
}
int DelElem(SqList &L,int i) //删除第i个元素
{ int j;
if (i<1 || i>L.length) //无效的参数i
return 0;
for (j=i;j<L.length;j++) //将位置为i的元素之后的元素前移
L.data[j-1]=L.data[j];
L.length--; //顺序表长度减1
return 1;
}
void DispList(SqList L) //输出顺序表
{ int i;
for (i=0;i<L.length;i++)
printf("%d ",L.data[i]);
printf("\n");
}
void CreateList(SqList &L,ElemType a[],int n) //整体创建顺序表L
{
int i,k=0; //k累计顺序表L中的元素个数
for (i=0;i<n;i++)
{
L.data[k]=a[i]; //向L中添加一个元素
k++; //L中元素个数增1
}
L.length=k; //设置L的长度
}
void Deletex(SqList &L,ElemType x)
{ int i,k=0;
for (i=0;i<L.length;i++)
if (L.data[i]!=x) //将不为x的元素插入到L中
{ L.data[k]=L.data[i];
k++;
}
L.length=k; //重置L的长度
}
void Delmaxe(SqList &L){
int maxe=0;
for(int i=0;i<GetLength(L);i++){
if(L.data[i] > maxe) {
maxe=L.data[i];
}
}
int l=0;
for(int i=0;i<GetLength(L);i++){
if(L.data[i] !=maxe) {
L.data[l] =L.data[i];
l++;
}
}
L.length =l;
}
int main()
{
SqList L;
int a[]={2,1,5,4,2,5,1,5,4};
int n=sizeof(a)/sizeof(a[0]);
CreateList(L,a,n);
DispList(L);
Delmaxe(L);
DispList(L);
DestroyList(L);
return 0;
}
A02:2.5 有序顺序表——删除重复元素
设计一个算法从有序顺序表中删除重复的元素,多个值相同的元素仅保留第一个。
#include <stdio.h>
#include<iostream>
using namespace std;
#define MaxSize 100
typedef int ElemType; //设置顺序表元素为int类型
typedef struct
{ ElemType data[MaxSize]; //存放顺序表的元素
int length; //顺序表的实际长度
} SqList; //顺序表类型声明
void InitList(SqList &L) //初始化顺序表L
{
L.length=0;
}
void DestroyList(SqList L) //销毁顺序表L
{
}
int GetLength(SqList L) //求长度
{
return L.length;
}
int GetElem(SqList L,int i,ElemType &e) //求第i个元素
{ if (i<1 || i>L.length) //无效的i值
return 0;
else
{ e=L.data[i-1];
return 1;
}
}
int Locate(SqList L,ElemType x) //查找第一个x元素的位置
{ int i=0;
while (i<L.length && L.data[i]!=x)
i++; //查找第1个值为x的元素
if (i>=L.length) return(0); //未找到返回0
else return(i+1); //找到后返回其逻辑序号
}
int InsElem(SqList &L,ElemType x,int i) //插入x作为第i个元素
{ int j;
if (i<1 || i>L.length+1) //无效的参数i
return 0;
for (j=L.length;j>i;j--) //将位置为i的元素及之后的元素后移
L.data[j]=L.data[j-1];
L.data[i-1]=x; //在位置i处放入x
L.length++; //顺序表长度增1
return 1;
}
int DelElem(SqList &L,int i) //删除第i个元素
{ int j;
if (i<1 || i>L.length) //无效的参数i
return 0;
for (j=i;j<L.length;j++) //将位置为i的元素之后的元素前移
L.data[j-1]=L.data[j];
L.length--; //顺序表长度减1
return 1;
}
void DispList(SqList L) //输出顺序表
{ int i;
for (i=0;i<L.length;i++)
printf("%d ",L.data[i]);
printf("\n");
}
void CreateList(SqList &L,ElemType a[],int n) //整体创建顺序表L
{
int i,k=0; //k累计顺序表L中的元素个数
for (i=0;i<n;i++)
{
L.data[k]=a[i]; //向L中添加一个元素
k++; //L中元素个数增1
}
L.length=k; //设置L的长度
}
void DelSame(SqList &L) //删除重复元素
{
int k=0;
for(int i=0;i<GetLength(L);i++){
if(Locate(L,L.data[i]) >k){
L.data [k]=L.data[i];
k++;
}
}
L.length = k;
}
int main()
{
SqList L;
int a[]={1,2,2,2,5,5,5};
int n=sizeof(a)/sizeof(a[0]);
CreateList(L,a,n);
DispList(L);
DelSame(L); //删除重复元素
DispList(L);
DestroyList(L);
}
A03:〖NOIP2005P〗陶陶摘苹果
每到秋天树上就会结出10个苹果。苹果成熟的时候,陶陶就会跑去摘苹果。陶陶有个30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试。
#include<iostream>
using namespace std;
int main()
{
int a[10];
for(int i=0;i<10;i++){
cin>>a[i];
}
int h,ans=0;
cin>>h;
h+=30;
for(int i=0;i<10;i++){
if(a[i]<=h){
ans++;
}
}
cout<<ans<<endl;
return 0;
}
A04:整数顺序表的并集、差集和交集
采用顺序表存储非空整数集合(同一个集合中没有相同的元素,两个集合中可能存在相同的元素),设计完成如下功能的算法并用相关数据进行测试。
①求两个集合A、B的并集C=A∪B
②求两个集合A、B的差集C=A-B
③求两个集合A、B的交集C=A∩B
#include <stdio.h>
#include<iostream>
#include<cstring>
using namespace std;
#define MaxSize 100
typedef int ElemType; //设置顺序表元素为int类型
typedef struct
{ ElemType data[MaxSize]; //存放顺序表的元素
int length; //顺序表的实际长度
} SqList; //顺序表类型声明
void InitList(SqList &L) //初始化顺序表L
{
L.length=0;
}
void DestroyList(SqList L) //销毁顺序表L
{
}
int GetLength(SqList L) //求长度
{
return L.length;
}
int Locate(SqList L,ElemType x) //查找第一个x元素的位置
{ int i=0;
while (i<L.length && L.data[i]!=x)
i++; //查找第1个值为x的元素
if (i>=L.length) return(0); //未找到返回0
else return(i+1); //找到后返回其逻辑序号
}
void DispList(SqList L) //输出顺序表
{ int i;
for (i=0;i<L.length;i++)
printf("%d ",L.data[i]);
printf("\n");
}
void CreateList(SqList &L,ElemType a[],int n) //整体创建顺序表L
{
int i,k=0; //k累计顺序表L中的元素个数
for (i=0;i<n;i++)
{
L.data[k]=a[i]; //向L中添加一个元素
k++; //L中元素个数增1
}
L.length=k; //设置L的长度
}
bool check(SqList l){
for(int i=l.length-1;i>=0 ;i--){
if(Locate(l,l.data[i])<=i&&Locate(l,l.data[i])!=0){
return 1;
}
}
return 0;
}
void CU(SqList l1,SqList l2){
SqList l3;
InitList(l3);
int k=0;
for(int i=0;i<l1.length ;i++){
l3.data [k]=l1.data [i];
k++;
l3.length =k;
}
for(int i=0;i<l2.length ;i++){
if(Locate(l3,l2.data [i])==0){
l3.data [k]=l2.data [i];
k++;
l3.length =k;
}
}
cout<<"CU:";
DispList(l3);
}
void CD(SqList l1,SqList l2){
SqList l3;
InitList(l3);
int k=0;
for(int i=0;i<l1.length ;i++){
if(Locate(l2,l1.data [i])==0){
l3.data [k]=l1.data [i];
k++;
l3.length =k;
}
}
cout<<"CD:";
DispList(l3);
}
void CI(SqList l1,SqList l2){
SqList l3;
InitList(l3);
int k=0;
for(int i=0;i<l1.length ;i++){
if(Locate(l2,l1.data [i])!=0&&Locate(l3,l1.data [i])==0){
l3.data [k]=l1.data [i];
k++;
l3.length =k;
}
}
cout<<"CI:";
DispList(l3);
}
int main()
{
SqList l1,l2;
InitList(l1);
InitList(l2);
int n;
cin>>n;
int a[n];
for(int i=0;i<n;i++){
cin>>a[i];
}
CreateList(l1,a,n);
cin>>n;
int b[n];
for(int i=0;i<n;i++){
cin>>b[i];
}
CreateList(l2,b,n);
if(check(l1)||check(l2)){
cout<<"Repeat Error!"<<endl;
}
else {
CU(l1,l2);
CD(l1,l2);
CI(l1,l2);
}
DestroyList(l1);
DestroyList(l2);
return 0;
}
A05:DNA排序
现在有一些长度相等的DNA串(只由ACGT四个字母组成),请将它们按照逆序对的数量多少排序。
逆序对指的是字符串A中的两个字符A[i]、A[j],具有i < j 且 A[i] > A[j] 的性质。如字符串”ATCG“中,T和C是一个逆序对,T和G是另一个逆序对,这个字符串的逆序对数为2。
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
struct node
{
int shu;
int xuhao;
string s;
}a[105];
bool cmp(node x,node y)
{
if(x.shu==y.shu ){
return x.xuhao<y.xuhao;
}
return x.shu<y.shu;
}
int main()
{
int m,n;
cin>>n>>m;
for(int i=0;i<m;i++)
{
string s1;
int shu1=0;
cin>>s1;
for(int j=0;j<n;j++)
{
if(s1[j]=='C'){
for(int k=j;k<n;k++){
if(s1[k]=='A'){
shu1++;
}
}
}
else if(s1[j]=='T'){
for(int k=j;k<n;k++){
if(s1[k]=='A'||s1[k]=='C'||s1[k]=='G'){
shu1++;
}
}
}
else if(s1[j]=='G'){
for(int k=j;k<n;k++){
if(s1[k]=='A'||s1[k]=='C'){
shu1++;
}
}
}
}
a[i].s=s1;
a[i].shu=shu1;
a[i].xuhao=i;
}
sort(a,a+m,cmp);
for(int i=0;i<m;i++)
{
cout<<a[i].s<<endl;
}
return 0;
}
//未AC代码
#include<iostream>
#include<string.h>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m;
struct mystring{
string str;
int num;
}s[50];
bool cmp(mystring a,mystring b){
return a.num <b.num ;
}
int GetReverse(string a) {
int sum = 0;
for (int i = 0; i < n-1; ++i) {
for (int j = i+1; j < n; ++j) {
if (a[i] > a[j]) ++sum;
}
}
return sum;
}
int main(){
cin>>n>>m;;
for(int i=1;i<=m;i++){
cin>>s[i].str;
}
for(int i=1;i<=n;i++){
s[i].num=GetReverse(s[i].str );
}
sort(s+1,s+1+m,cmp);
for(int i=1;i<=m;i++){
cout<<s[i].str <<endl;
}
return 0;
}
A06:垂直直方图
输入4行全部由大写字母组成的文本,输出一个垂直直方图,给出每个字符出现的次数。注意:只用输出字符的出现次数,不用输出空白字符,数字或者标点符号的输出次数。
#include<iostream>
#include<cstring>
using namespace std;
int main(){
int n[40]={0};
string s1,s2,s3,s4;
getline(cin, s1);int l1=s1.length() ;
getline(cin, s2);int l2=s2.length() ;
getline(cin, s3);int l3=s3.length() ;
getline(cin, s4);int l4=s4.length() ;
for(int i=0;i<l1;i++){
if(s1[i]-'A'>=0&&s1[i]-'A'<=26) n[s1[i]-'A']++;
}
for(int i=0;i<l2;i++){
if(s2[i]-'A'>=0&&s2[i]-'A'<=26) n[s2[i]-'A']++;
}
for(int i=0;i<l3;i++){
if(s3[i]-'A'>=0&&s3[i]-'A'<=26) n[s3[i]-'A']++;
}
for(int i=0;i<l4;i++){
if(s4[i]-'A'>=0&&s4[i]-'A'<=26) n[s4[i]-'A']++;
}
int maxn=0;
for(int i=0;i<26;i++)//找到最大值
{
maxn=maxn>n[i]?maxn:n[i];
}
for(int i=maxn-1;i>=0;i--)
{
for(int j=0;j<=27;j++)
{
if(n[j]>=maxn) cout<<'*'<<' ';
else if(maxn>n[j]) cout<<' '<<' ';
}
cout<<endl;
maxn--;
}
cout<<"A B C D E F G H I ";
cout<<"J K L M N O P Q R ";
cout<<"S T U V W X Y Z "<<endl;
return 0;
}
A07:两个整数相互交换
#include<iostream>
#include<string.h>
#include<cmath>
#include<algorithm>
using namespace std;
int main(){
int a,b;
cin>>a>>b;
swap(a,b);
cout<<a<<" "<<b<<endl;
return 0;
}
A08:2.1 顺序表——调整数据元素
假设一个顺序表L中所有元素为整数,设计一个算法调整该顺序表,使其中所有小于零的元素移动到所有大于等于零的元素的前面。
#include <stdio.h>
#include <iostream>
using namespace std;
#define MaxSize 100
typedef int ElemType; //设置顺序表元素为int类型
typedef struct
{ ElemType data[MaxSize]; //存放顺序表的元素
int length; //顺序表的实际长度
} SqList; //顺序表类型声明
void InitList(SqList &L) //初始化顺序表L
{
L.length=0;
}
void DestroyList(SqList L) //销毁顺序表L
{
}
int GetLength(SqList L) //求长度
{
return L.length;
}
int GetElem(SqList L,int i,ElemType &e) //求第i个元素
{ if (i<1 || i>L.length) //无效的i值
return 0;
else
{ e=L.data[i-1];
return 1;
}
}
int Locate(SqList L,ElemType x) //查找第一个x元素的位置
{ int i=0;
while (i<L.length && L.data[i]!=x)
i++; //查找第1个值为x的元素
if (i>=L.length) return(0); //未找到返回0
else return(i+1); //找到后返回其逻辑序号
}
int InsElem(SqList &L,ElemType x,int i) //插入x作为第i个元素
{ int j;
if (i<1 || i>L.length+1) //无效的参数i
return 0;
for (j=L.length;j>i;j--) //将位置为i的元素及之后的元素后移
L.data[j]=L.data[j-1];
L.data[i-1]=x; //在位置i处放入x
L.length++; //顺序表长度增1
return 1;
}
int DelElem(SqList &L,int i) //删除第i个元素
{ int j;
if (i<1 || i>L.length) //无效的参数i
return 0;
for (j=i;j<L.length;j++) //将位置为i的元素之后的元素前移
L.data[j-1]=L.data[j];
L.length--; //顺序表长度减1
return 1;
}
void DispList(SqList L) //输出顺序表
{ int i;
for (i=0;i<L.length;i++)
printf("%d ",L.data[i]);
printf("\n");
}
void CreateList(SqList &L,ElemType a[],int n) //整体创建顺序表L
{
int i,k=0; //k累计顺序表L中的元素个数
for (i=0;i<n;i++)
{
L.data[k]=a[i]; //向L中添加一个元素
k++; //L中元素个数增1
}
L.length=k; //设置L的长度
}
// 在此处补充你的代码
void Move(SqList &L)
{ int i=0,j=L.length-1;
while (i<j)
{ while (L.data[i]<0) i++; //从前向后
while (L.data[j]>=0) j--; //从后向前
if (i<j)
swap(L.data[i],L.data[j]); //交换这两元素
}
}
// 在此处补充你的代码
int main()
{
SqList L;
int a[]={2,-1,0,2,-2,3,-3};
int n=sizeof(a)/sizeof(a[0]);
CreateList(L,a,n);
DispList(L);
Move(L);// 移动求解算法
DispList(L);
DestroyList(L);
return 0;
}
A09:顺序表区间元素删除
描述
若一个线性表L采用顺序存储结构存储,其中所有的元素为整数。设计一个算法,删除元素值在[x,y]之间的所有元素,要求算法的时间复杂度为O(n),空间复杂度为O(1)。
输入
三行数据,第一行是顺序表的元素个数,第二行是顺序表的元素,第三行是x和y。
输出
删除元素值在[x,y]之间的所有元素后的顺序表。
//投机取巧版本
#include<iostream>
using namespace std;
int main(){
int n;
cin>>n;
int a[n];
for(int i=0;i<n;i++){
cin>>a[i];
}
int x,y;
cin>>x>>y;
for(int i=0;i<n;i++){
if(a[i]<x||a[i]>y){
cout<<a[i]<<" ";
}
}
}
include <stdio.h>
#include <iostream>
using namespace std;
#define MaxSize 100
typedef int ElemType;
struct SqList
{ ElemType data[MaxSize];
int length;
};
void InitList(SqList &L){
L.length=0;
}
void createlist(SqList &l,int a[],int n){
int k=0;
for(int i=0;i<n;i++){
l.data [k]=a[i];
k++;
l.length =k;
}
}
void output(SqList l){
for(int i=0;i<l.length ;i++){
cout<<l.data[i]<<" ";
}
cout<<endl;
}
void deixy(SqList l,int x,int y){
int k=0;
for(int i=0;i<l.length ;i++){
if((l.data [i]<x ) || (l.data [i]>y)){
l.data [k]=l.data [i];
k++;
}
}
l.length = k;
output(l);
}
int main()
{
int n;
cin>>n;
int a[n];
for(int i=0;i<n;i++){
cin>>a[i];
}
SqList l;
InitList(l);
createlist(l,a,n);
int x,y;
cin>>x>>y;
deixy(l,x,y);
return 0;
}
A10:整数顺序表的基本运算
有必要的讲解我都以注释的形式写在代码里,为了跟大家上课学的内容保持一致性,我基本都是用书上的函数名、格式写的代码,虽然这样分散的代码简直让找bug的人看瞎眼。不熟悉的同学,建议手推一遍插入和删除元素的算法,不要记错循环顺序。
#include <stdio.h>
#include <iostream>
using namespace std;
#define MaxSize 100
typedef int ElemType;
struct SqList
{ ElemType data[MaxSize];
int length;
};
void InitList(SqList &L){
L.length=0;
}
void createlist(SqList &l,int a[],int n){
int k=0;
for(int i=0;i<n;i++){
l.data [k]=a[i];
k++;
l.length =k;
}
}
void output(SqList l){
for(int i=0;i<l.length ;i++){
cout<<l.data[i]<<" ";
}
cout<<endl;
}
void del1(SqList &l){
for(int i=1;i<l.length ;i++){
l.data[i-1]=l.data[i];
}
l.length--;
}
void insl(SqList &l,int x){
for(int i=l.length;i>=2;i--){
l.data [i]=l.data [i-1];
}
l.length++;
l.data[1]=x;
}
int findx(SqList &l,int x){
int k=0;
while(k<l.length && l.data[k]!=x) k++;
if(k>=l.length ) return 0;
else return k+1;
}
int main()
{
int n;
cin>>n;
int a[n];
for(int i=0;i<n;i++){
cin>>a[i];
}
SqList l;
InitList(l);
createlist(l,a,n);
//输出
output(l);
del1(l);
output(l);
cout<<l.length <<endl;
insl(l,100);
output(l);
cout<<findx(l,100)<<endl;
return 0;
}
A11:单链表的基本运算
#include <iostream>
using namespace std;
#define T char
struct node{ //定义链表
T data;
node *next;
};
//头结点用head表示
void initList(node *&head){ //初始化函数
head=new node();
head->next=NULL;
head->data =0;
}
void destoryList(node *&head){ //销毁链表
node *pre=head;
node *p=head->next; //从头结点开始删除
while(p!=NULL){
delete pre;
pre=p;
p=p->next;
}
}
int getLength(node *head){ //求长度
int count=0;
node *p=head->next;
while(p!=NULL){
p=p->next;
count++;
}
return count;
}
int findValue(node *head,T value){ //找到值为value的结点
node *p=head->next;
int count=1;
while(p!=NULL&&p->data!=value)
{
p=p->next;
count++;
}
return count;
}
void insElem(node *&head,T value,int i){ //在第i个元素后插入值为value的结点
node *p=head->next;
int count=1;
while(p!=NULL&&count!=i){
p=p->next;
count++;
}
node *q=new node();
q->data=value;
q->next=p->next;
p->next=q;
}
void deleElem(node *&head,int i){ //删除第i个元素
node *p=head;
int count=1;
while(p!=NULL&&count!=i){
p=p->next;
count++;
}
node *q=p->next;
p->next=q->next;
delete q;
}
void output(node *head){ //输出
node *p=head->next;
while(p!=NULL){
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
void createList_tail(node *head,T a[],int len){ //尾插法创建链表
node *tc=head;
for(int i=0;i<len;i++){
node *s=new node();
s->data=a[i];
tc->next=s;
tc=s;
}
}
bool check_null(node *head){
node * p = head->next ;
if(p!=NULL) return 1;
else return 0;
}
void output_x(node *head,int x){
node *p=head;
int count=1;
while(p!=NULL&&count!=x){
p=p->next;
count++;
}
cout<< p->next->data <<endl;
}
int main()
{
// (1)初始化单链表L,输出L->next的值
node *head;
initList(head);
cout<< head->next <<endl;
// (2)依次采用尾插法插入元素:输入分两行数据,第一行是尾插法需要插入的字符数据的个数,第二行是具体插入的字符数据。
T a[10000];
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
createList_tail(head,a,n);
// (3)输出单链表L
output(head);
// (4)输出单链表L的长度
cout<<getLength(head)<<endl;
// (5)判断单链表L是否为空;
if(check_null(head))cout<<"no"<<endl;
else cout<<"yes"<<endl;
// (6)输出单链表L的第3个元素;
output_x(head,3);
// (7)输出元素a的位置;
cout<<findValue(head,'a')<<endl;
// (8)在第4个元素位置上插入‘x’元素;
insElem(head,'x',3);
// (9)输出单链表L;
output(head);
// (10)删除L的第3个元素;
deleElem(head,3);
// (11)输出单链表L;
output(head);
// (12)释放单链表L。
destoryList(head);
return 0;
}
A12:单链表的插入和显示操作
#include <malloc.h>
#include <iostream>
using namespace std;
typedef int ElemType;
#define MAX_SIZE 100
typedef struct node
{
ElemType data; //数据域
struct node *next; //指针域
} SLinkNode; //单链表结点类型
void CreateListR(SLinkNode *&L, ElemType a[], int n) //尾插法建表
{
SLinkNode *s, *tc; int i;
L = (SLinkNode *)malloc(sizeof(SLinkNode)); //创建头结点
tc = L; //tc为L的尾结点指针
for (i = 0; i < n; i++)
{
s = (SLinkNode *)malloc(sizeof(SLinkNode));
s->data = a[i]; //创建存放a[i]元素的新结点s
tc->next = s; //将s结点插入tc结点之后
tc = s;
}
tc->next = NULL; //尾结点next域置为NULL
}
int InsElemSpe(SLinkNode *&L) //插入结点
{
int maxa=0;int maxi=0; int count =1;
SLinkNode *pre = L, *p = pre->next;
while (p != NULL)
{
if(p->data > maxa){
maxa=p->data;
maxi=count;
}
pre = p; p = p->next;count++; //pre、p同步后移
}
//cout<<"debug "<<maxi<<endl;
SLinkNode *s_temp=(SLinkNode*)malloc(sizeof(SLinkNode));
s_temp->data = maxa+10;
int i=0;
pre = L;
p = pre->next;
while(i!=maxi-1&&p!=NULL){
i++;
pre=p;
p=p->next ;
}
s_temp->next =p->next ;
p->next =s_temp;
return 1; //插入运算成功,返回1
}
void DispList(SLinkNode *L) //输出单链表
{
SLinkNode *p = L->next;
while (p != NULL)
{
cout<<p->data<<" ";
p = p->next;
}
cout<<endl;
}
void DestroyList(SLinkNode *&L) //销毁单链表L
{
SLinkNode *pre = L, *p = pre->next;
while (p != NULL)
{
free(pre);
pre = p; p = p->next; //pre、p同步后移
}
free(pre);
}
int main()
{
ElemType a[MAX_SIZE];
SLinkNode *L;
int nlength;
cin >> nlength;
for (int i = 0; i < nlength; i++)
cin >> a[i];
CreateListR(L, a, nlength);
InsElemSpe(L);
DispList(L);
DestroyList(L);
return 0;
}
A13 整数单链表的基本运算-1
设计整数单链表的基本运算程序,并用相关数据进行测试
输入
顺序输入单链表A的各个元素
输出
第一行:创建单链表A后,输出所有元素
第二行:删除第一个元素,输出删除后的所有元素
第三行:输出删除元素后表的长度
第四行:在第二元素处插入一个新的元素100
第五行:输出第一个元素100所在位置
#include <iostream>
using namespace std;
struct node{ //定义链表
int data;
node *next;
};
//头结点用head表示
void initList(node *&head){ //初始化函数
head=new node();
head->next=NULL;
}
void destoryList(node *&head){ //销毁链表
node *pre=head,*p=head->next; //从头结点开始删除
while(p!=NULL){
delete pre;
pre=p;
p=p->next;
}
}
int getLength(node *head){ //求长度
int count=0;
node *p=head->next;
while(p!=NULL){
p=p->next;
count++;
}
return count;
}
int findValue(node *head,int value){ //找到值为value的结点
node *p=head->next;
int count=1;
while(p!=NULL&&p->data!=value)
{
p=p->next;
count++;
}
return count;
}
void insElem(node *&head,int value,int i){ //在第i个元素后插入值为value的结点
node *p=head->next;
int count=1;
while(p!=NULL&&count!=i){
p=p->next;
count++;
}
node *q=new node();
q->data=value;
q->next=p->next;
p->next=q;
}
void deleElem(node *&head,int i){ //删除第i个元素
node *p=head;
int count=1;
while(p!=NULL&&count!=i){
p=p->next;
count++;
}
node *q=p->next;
p->next=q->next;
delete q;
}
void output(node *head){ //输出
node *p=head->next;
while(p!=NULL){
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
void createList_tail(node *head,int a[],int len){ //尾插法创建链表
node *tc=head;
for(int i=0;i<len;i++){
node *s=new node();
s->data=a[i];
tc->next=s;
tc=s;
}
}
int main()
{
node *head;
initList(head);
int a[10000];
for(int i=0;i<6;i++)cin>>a[i];
createList_tail(head,a,6);
output(head);
deleElem(head,1);
output(head);
cout<<getLength(head)<<endl;
insElem(head,100,1);
output(head);
cout<<findValue(head,100)<<endl;
destoryList(head);
return 0;
}
A14 整数单链表的基本运算-2
设计有序整数单链表的插入运算程序,并用相关数据进行测试
#include <iostream>
using namespace std;
struct node{
int data;
node *next;
};
//头结点用head表示
void initList(node *&head){ //无值初始化
head=new node();
head->next=NULL;
}
void destoryList(node *&head){ //销毁
node *pre=head,*p=head->next; //从头结点开始删除
while(p!=NULL){
delete pre;
pre=p;
p=p->next;
}
}
void output(node *head){
node *p=head->next;
while(p!=NULL){
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
void createList_tail(node *head,int a[],int len){
node *tc=head;
for(int i=0;i<len;i++){
node *s=new node();
s->data=a[i];
tc->next=s;
tc=s;
}
}
int main()
{
node *head;
initList(head);
int a[1000],value;
for(int i=0;i<6;i++)cin>>a[i];
cin>>value;
createList_tail(head,a,6);
output(head);
node *p=head->next;
while(p!=NULL&&p->next->data<=value)
p=p->next;
node *s=new node();
s->data=value;
s->next=p->next;
p->next=s;
output(head);
destoryList(head);
return 0;
}
A15 循环单链表的基本运算
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
#define MaxSize 100
typedef char ElemType;
typedef struct node
{
ElemType data;
struct node *next;
}SLinkNode;
void InitList(SLinkNode *&L)
{
L=(SLinkNode *)malloc(sizeof(SLinkNode));
L->next=L;
}
void DestroyList(SLinkNode *&L)
{
SLinkNode *pre=L,*p=pre->next;
while(p!=L)
{
free(pre);
pre=p;
p=p->next;
}
free(pre);
}
int GetLength(SLinkNode *L)
{
int i=0;
SLinkNode *p=L->next;
while(p!=L)
{
i++;
p=p->next;
}
return i;
}
int InELem(SLinkNode *&L,ElemType x,int i)
{
int j=1;
SLinkNode *pre=L,*p=pre->next,*s;
if(i<=0)return 0;
while(p!=L&&j<i)
{
j++;
pre=p;
p=p->next;
}
if(p==L&&i>j+1)return 0;
else
{
s=(SLinkNode *)malloc(sizeof(SLinkNode));
s->data=x;
s->next=pre->next;
pre->next=s;
return 1;
}
}
int DelElem(SLinkNode *&L,int i)
{
int j=0;
SLinkNode *p=L,*post;
if(i<=0)return 0;
while(p->next!=L&&j<i-1)
{
j++;
p=p->next;
}
if(p->next==L)return 0;
else
{
post=p->next;
if(post==L)return 0;
else
{
p->next=post->next;
free(post);
return 1;
}
}
}
void GreateListR(SLinkNode *&L,ElemType a[],int n)
{
SLinkNode *s,*tc;
int i;
L=(SLinkNode*)malloc(sizeof(SLinkNode));
tc=L;
for(i=0;i<n;i++)
{
s=(SLinkNode*)malloc(sizeof(SLinkNode));
s->data=a[i];
tc->next=s;
tc=s;
}
tc->next=L;
}
char GetElem(SLinkNode *L,int i,ElemType &e)
{
int j=1;
SLinkNode *p=L->next;
if(i<=0)return 0;
while(p!=L&&j<i)
{
j++;
p=p->next;
}
if(p==L)return 0;
else
{
e=p->data;
return e;
}
}
int Locate(SLinkNode *L,ElemType x)
{
int i=1;
SLinkNode *p=L->next;
while(p!=L&&p->data!=x)
{
p=p->next;
i++;
}
if(p==L)return 0;
else return i;
}
void JudgeNULL(SLinkNode *L)
{
if(L->next==NULL)
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
}
int Judge(SLinkNode *L)
{
if(L->next==L)
return 1;
else
return 0;
}
void DispList(SLinkNode *L)
{
SLinkNode *p=L->next;
while(p!=L)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
int main()
{
SLinkNode *L;
InitList(L);
cout<<Judge(L)<<endl;
int n,i;
char test1;
cin>>n;
char arr[n];
for(i=0;i<n;i++)
cin>>arr[i];
GreateListR(L,arr,n);
DispList(L);
cout<<GetLength(L)<<endl;
JudgeNULL(L);
cout<<GetElem(L,3,test1)<<endl;
cout<<Locate(L,97)<<endl;
InELem(L,119,4) ;
DispList(L);
DelElem(L,5);
DispList(L);
DestroyList(L);
}