数据结构与算法--第二章题解

数据结构与算法–第二章题解

题目传送门

食用建议

1.不要直接CTRL+C一波带走,要不可能会被老师一波带走
2.可以手抄一边模板,会有奇效;
3.调调数据在本地跑一下也很有成就感,直接就理解了。

模板 --顺序表

#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);
 } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值