关于顺序表一些问题及解决

(1) 定义顺序表结构,并实现顺序表的建立,并输出顺序表的全部结点值(遍历)。(顺序表的建立和遍历为在顺序表上的运算,用自定义函数实现)

(2)在题目一的基础上实现如下算法:设计一个高效的算法,从有序顺序表L中删除所有值介于x和y之间的所有元素,要求时间复杂度为O(n)。(顺序表中元素类型为int)

(3)在题目一的基础上实现如下算法:已知顺序表L中的元素为int,请写一时间复杂度为O(n)、空间复杂度为O(1)的算法,将L中的奇数元素排在前面,偶数元素排在后面

(4)在题目一的基础上实现如下算法:编写算法,在一非递减的顺序表L中,删除所有值相等的多余元素。要求时间复杂度为O(n),空间复杂度为O(1);

(5)在题目一的基础上实现如下算法:实现顺序表的就地逆置算法,即在原表的存储空间将线性表(a1,a2,a3,…,an)逆置为(an,an-1,an-2,…,a1)。

问题1:我们用结构体定义一个顺序表,并让其具有重置和输入输出功能

具体实现如下:较为简单就不分析代码实现过程

typedef struct{//结构体变量
    int elem[MAXSIZE];
    int last;
}SeqList;
void chushihualist(SeqList *L){//格式化表
    L-> last= - 1;
}
void chuangjianlist(SeqList *L){//创建表
    int n,i=0;
    printf("输入数据表长度n:");
    scanf("%d",&n);
    printf("输入%d个元素:\n",n);
    while(i<n){
        scanf("%d",&L->elem[i]);
        i++;
    }
    L->last=n-1;
}

问题二:删除顺序表内一定范围的元素:

在这里我们首先遍历所有元素,并判断顺序表的的元素是否至少为2个,然后定义一个int变量k=0用来记录介于x到y之间的元素,每发现一个我们K++;然后我们让[i-k]=[i],直接覆盖掉介于x到y间的元素;其次我们还需重置顺序表下标last让其不输出多余元素。然后我们调用输出函数将其输出。其满足时间复杂度O(n).

oid shanchux_y(SeqList *L)//删除介于x到y间的函数。
{
    int x,y,s;
    printf("请输入删除元素范围");
    scanf("%d %d",&x,&y);
    int k=0;
    if(x>=y||L->last==0)
        s=0;
    else
    {
        for(int i=0;i<=L->last;i++)
        {
            if(L->elem[i]>x&&L->elem[i]<y)
                k++;
            else
                L->elem[i-k]=L->elem[i];
        }
    }
    L->last=(L->last)-k;
    s=1;
    if(s==1)
    {
        printf("删除范围%d到%d后顺序表为\n",x,y);
        shuchulist(*L);
    }
}

问题三:奇前偶后排序

在这里我们使用双指针,一个指针指向第一个元素,一个指针指向最后一个元素,然后交换奇数偶数的位置,直到两指针相遇。

void swap(int *a,int *b)
{
    int t=*a;
    *a=*b;
    *b=t;
}
void jioupaixu(SeqList *L)//将奇数排在前面偶数排在后面。
{
    int i=0,j=L->last;
    while(i<j){
        while(i<j&&L->elem[i]%2==1)i++;
        while(i<j&&L->elem[j]%2==0)j--;
        if(i<j)swap(&L->elem[i],&L->elem[j]);
    }
    printf("奇偶排序后顺序表为:\n");
    shuchulist(*L);
}

问题4:非递减数中删除多余等值元素

首先解释一下非递减数及后面的数要求大于或等于前面的数eg:1 2 2 3 3;非递增反之。

可以使用双指针的方法来实现。定义两个指针阅和j,初始时i=0,j=1。从头开始遍历顺序表,如果a[i]和a中相等,则j++;否则将a[]赋值给a[i+1](在这里我们定义一个int k=0,让其记录赋值次数方便重置表长),i++,j++。最后将i+1赋值给表长即可。最后重置表长

void shanchudengzhi(SeqList *L)//在非递减数列中删除等值多余元素
{
    int i=0,j=1,k=0;
    if(L->last==-1||L->last==0){
        printf("无法删除!");
        return;
    }
    else{
        while(j<=L->last){
            if(L->elem[i]==L->elem[j])
                j++;
            else{
                L->elem[++i]=L->elem[j++];
                }
        }
        while(i<=L->last-1){
            L->elem[++i]=0;
            k++;
        }
        L->last=L->last-k;
    }
    printf("删除等值多余数后顺序表为:\n");
    shuchulist(*L);
}

问题5;逆置输出

我们将表从中对折让元素第一位和最后一位交换,第二位和倒数第二位交换......以此类推,随着程序的执行i++,自然而然的交换到中间元素,较简单读者自行理解

void nizhilist(SeqList *L)//逆置输出
{
    int i,t;
    if(L->last>=1){
    for(i=0;i<(L->last+1)/2;i++)
    {
        t=L->elem[i];
        L->elem[i]=L->elem[L->last-i];
        L->elem[L->last-i]=t;
    }
    printf("逆置元素后表中的元素为:\n");
    shuchulist(*L);}
    else{
        printf("无法逆置!\n");
         return;
    }
}    

全局代码;

在主函数中使用switch语句每个case语句调用一个函数解决问题,再使用while使之不断运行,并打印一个菜单增强可读性。

int main(void)
{
    int choice;
    SeqList L;
    while(1){
        menu();
    printf("请选择菜单:");
    scanf("%d",&choice); 
    if(choice==0) break;
    switch(choice){
    case 4:chushihualist(&L);break;
    case 1:chuangjianlist(&L);break;
    case 2:shuchulist(L);break;
    case 3:shanchux_y(&L);break;
    case 5:jioupaixu(&L);break;
    case 6:shanchudengzhi(&L);break;
    case 7:nizhilist(&L);break;
    default:printf("输入错误!请重新输入\n");
    }
    }return 0;
}

全部代码实现

#include<stdio.h>
#define MAXSIZE 100
void menu()
{
    printf("1.创建表     2.输出表\n");
    printf("3.删除范围   4.初始化表格\n");
    printf("5.奇偶排序   6.删除多余数\n");
    printf("7.逆置顺序表 0.退出\n");
}
typedef struct{
    int elem[MAXSIZE];
    int last;
}SeqList;
void chushihualist(SeqList *L){//格式化表
    L-> last= - 1;
}
void chuangjianlist(SeqList *L){//创建表
    int n,i=0;
    printf("输入数据表长度n:");
    scanf("%d",&n);
    printf("输入%d个元素:\n",n);
    while(i<n){
        scanf("%d",&L->elem[i]);
        i++;
    }
    L->last=n-1;
}
void shuchulist(SeqList L){//输出表
    int i;
    if(L.last==-1)
        printf("表空!");
    for(i=0;i<=L.last;i++)
        printf(" %d",L.elem[i]);
    printf("\n");
}
void shanchux_y(SeqList *L)//删除介于x到y间的函数。
{
    int x,y,s;
    printf("请输入删除元素范围");
    scanf("%d %d",&x,&y);
    int k=0;
    if(x>=y||L->last==0)
        s=0;
    else
    {
        for(int i=0;i<=L->last;i++)
        {
            if(L->elem[i]>x&&L->elem[i]<y)
                k++;
            else
                L->elem[i-k]=L->elem[i];
        }
    }
    L->last=(L->last)-k;
    s=1;
    if(s==1)
    {
        printf("删除范围%d到%d后顺序表为\n",x,y);
        shuchulist(*L);
    }
}
void swap(int *a,int *b)
{
    int t=*a;
    *a=*b;
    *b=t;
}
void jioupaixu(SeqList *L)//将奇数排在前面偶数排在后面。
{
    int i=0,j=L->last;
    while(i<j){
        while(i<j&&L->elem[i]%2==1)i++;
        while(i<j&&L->elem[j]%2==0)j--;
        if(i<j)swap(&L->elem[i],&L->elem[j]);
    }
    printf("奇偶排序后顺序表为:");
    shuchulist(*L);
}
void shanchudengzhi(SeqList *L)//在非递减数列中删除等值多余元素
{
    int i=0,j=1,k=0;
    if(L->last==-1||L->last==0){
        printf("无法删除!");
        return;
    }
    else{
        while(j<=L->last){
            if(L->elem[i]==L->elem[j])
                j++;
            else{
                L->elem[++i]=L->elem[j++];
                }
        }
        while(i<=L->last-1){
            L->elem[++i]=0;
            k++;
        }
        L->last=L->last-k;
    }
    printf("删除等值多余数后顺序表为:\n");
    shuchulist(*L);
}
void nizhilist(SeqList *L)//逆置输出
{
    int i,t;
    if(L->last>=1){
    for(i=0;i<(L->last+1)/2;i++)
    {
        t=L->elem[i];
        L->elem[i]=L->elem[L->last-i];
        L->elem[L->last-i]=t;
    }
    printf("逆置元素后表中的元素为:\n");
    shuchulist(*L);}
    else{
        printf("无法逆置!\n");
         return;
    }
}    
int main(void)
{
    int choice;
    SeqList L;
    while(1){
        menu();
    printf("请选择菜单:");
    scanf("%d",&choice); 
    if(choice==0) break;
    switch(choice){
    case 4:chushihualist(&L);break;
    case 1:chuangjianlist(&L);break;
    case 2:shuchulist(L);break;
    case 3:shanchux_y(&L);break;
    case 5:jioupaixu(&L);break;
    case 6:shanchudengzhi(&L);break;
    case 7:nizhilist(&L);break;
    default:printf("输入错误!请重新输入\n");
    }
    }return 0;
}
  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GOD.CHEN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值