数据结构编程题系列(一)顺序表

745 阅读4分钟

1.1.1 翻转算法

​ 1.逆序数组

​ 2.在顺序表A[m+n]中有A1[m]和A2[n],将A2放在A1前。

​ 先全部逆序,再分别逆序前n个和后m个。

​ ps:思考将顺序表中的元素左移P个位置,方法同上。

1.1.2 排列组合

​ 1.输出从n个数中取出所有k 个数的所有组合(k<=n)

  //A为原始数组
 //start为遍历起始位置
  //result保存结果,为一维数组
  //count为result数组的索引值,起辅助作用
  //k为要选取的元素个数
  //n为原始数组的长度,为定值
void combine(int* A, int start, int* result, int count, const int k, const int n)
{
	int i=0;
	for (i=start;i<n+1-count;i++)
	{
		result[count-1]=i;
		if (count-1==0)	//输出结果 
		{
			int j;
			for (j=k-1;j>=0;j--)
				printf("%d\t",A[result[j]]);
			printf("\n");
 	   }
 	   else
			combine(A,i+1,result,count-1,k,n);
   }
}

​ 2.给定一个整数数组b[0..N-1],b中连续的相等元素构成的子序列称为平台。试设计算法,求出b中最长平台的长度。

void Platform (int b[ ], int N)
//求具有N个元素的整型数组b中最长平台的长度。
{
    l=1;k=0;j=0;i=0;
    while(i<n-1)
    {
        while(i<n-1 && b[i]==b[i+1]) 
            i++;
        if(i-j+1>l)
        {
            l=i-j+1;
            k=j;
        }   //局部最长平台
        i++;
        j=i; 
    }                  //新平台起点
    printf(“最长平台长度%d,在b数组中起始下标为%d”,l,k);
}

​ 3.若S是n个元素的集合,则S的幂集P(S)定义为S所有子集的集合。例如,S=(a,b,c),P(S)={() ,(a),(b),(c),(a,b),(a,c),(b,c),(a,b,c)}给定S,写一递归算法求P(S)。

void comb(int S[],int n,int P[],int i,int k)
//从集合(1..n)中选取k(k<=n)个元素的所有组合
{
    if (k==0) printf(P);
    else if(k<=n) 
    {
        P[i]=S[i]; 
        comb(P,i+1,k-1); comb(P,i+1,k); 
    }
}
void allSets(int S[],int n)
{
	int i;
    int P[maxsize];
    for(i=0;i<=n;i++)
    {
        comb(S,n,P,1,i);
    }
}

​ 3.有n个元素放在数组A中,输出这些元素的全排列(递归)。

void perm(int A[],int p,int q)
{
    int i,j;
    int temp;
    if(p==q)
    {
        printf(A[p]);
    }
    else
    {
        for(i=p;i<=q;i++)
        {
            temp = A[i];
            A[i] = A[p];
            A[p] = temp;
            perm(A,P+1,q);
            temp = A[i];
            A[i] = A[p];
            A[p] = temp;
        }
    }
}

1.1.3 数量问题

​ 1.找到顺序表中的元素,个数> n/2

​ (1)依次扫描每个数,将扫描的数放入c中,若下一个数与c相同,则count++,否则count--,当count==0时,将遇到的下一个元素放入c中,count=1,继续。

​ (2)再扫描一次数组,若c出现的次数大于n/2则为主元素。

1.1.4 判断问题

​ 1.给定一个整数数组,你需要寻找一个连续的子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。

​ 解:两个标志,一个记录第一次出现非升序的下标,另一个记录最后一次非升序的下标。

1.1.5 排序问题

​ 1.设任意n个整数存放于数组A(1:n)中,试编写程序,将所有正数排在所有负数前面

void Arrange(int A[],int n) 
//n个整数存于数组A中,本算法将数组中所有正数排在所有负数的前面
{
    int i=0,j=n-1,x;  //用类C编写,数组下标从0开始
    while(i<j)
    {
        while(i<j && A[i]>0)  
            i++;
        while(i<j && A[j]<0)  
            j--;
        if(i<j) 
        {
            x=A[i]; 
            A[i++]=A[j]; 
            A[j--]=x; 
        }//交换A[i] 与A[j]
    }
}

​ 2.设计一个算法,把整数数组中所有的偶数放到所有的奇数之前。要求时间、空间效率尽可能高。

​ 将上题中判定正数(A[i]>0)改为判偶数(A[i]%2==0),将判负数(A[j]<0)改为(A[j]%2!=0)

​ 3.设计算法将数组A[1..n]调整为左右两部分,使的左边所有的元素小于右边的所有元素,并给出这一划分的分界位置。

​ 利用快速排序思想一趟划分

int Partition(int A[],int n)  
//将n个元素的数组A调整为左右两部分,且左边所有元素小于右边所有元素,返回分界位置。
{
    int i=0,j=n-1,rp=A[0];  //设数组元素为整型
    while(i<j)
    {
        while(i<j &&A[j]>=rp)  
            j--;
        while(i<j &&A[i]<=rp)  
            i++;
        if(i<j) 
        { 
            x=A[i];
            A[i]=A[j]; 
            A[j]=x; 
        }
    }
    A[i]=rp; 
    return(i);   //分界元素
}

​ 4.用递归算法求出数组中的最大值和最小值。

void MinMaxValue(int A[],int n,int &max,int &min){
    if(n>=0){
        if(max<A[n]) 
            max=A[n];
        if(min>A[n])
            min=A[n];
        MinMaxValue(A,n-1,max,min);
    }
}