数据结构之王道顺序表大题

#include<stdio.h>
#define Maxsize 50
typedef struct{
    int data[Maxsize];
    int length;
} Seqlist;

#pragma region 基础操作 

//插入多个元素
void InsertElements(Seqlist *seq,int data[],int count)
{
    for (int i = 0; i < count; i++)
    {
        seq->data[i] = data[i];
        seq->length ++;
    }
}
void InitSeqlist(Seqlist *seq)
{
    seq->length=0;
}
int InsertElement(Seqlist *seq,int pos,int x)
{
    //超出范围
    if (seq->length>Maxsize)  return 0;
    //如果不满足条件说明是尾插,直接跳过for循环进入赋值阶段
    for (int i = seq->length-1; i > pos-1; i--)
    {
        seq->data[i+1]=seq->data[i];
    }
    seq->data[pos]=x;
    seq->length++;    
    return 1;
}
void ShowSeqlist(Seqlist seq)
{
    printf("------------------------------\n");
    for (int i = 0; i < seq.length; i++)
    {
        printf("the %d position is %d\n",i+1,seq.data[i]);
    }
    printf("------------------------------\n");
}
int DeleteElement(Seqlist *seq,int pos)
{
    if(seq->length==0) return -1;
    //这个数据通过指针返回
    int tem=seq->data[pos];
    for (int i = pos; i < seq->length-1; i++)
    {
        seq->data[i]=seq->data[i+1];
    }
    seq->length--;
    return tem;
}
int FindByContent(Seqlist *seq,int con)
{
    for (int i = 0; i < seq->length; i++)
    {
        if(seq->data[i]==con) return i;
    }
    return -1;   
}

#pragma endregion
#pragma region 逆序问题

/**
 * Q1
 * 将一长度为n的数组的前端k个元素逆序后移动到数组后段,要求原数组元素不丢失,其余元素位置无关紧要。
 * 将数据整体逆序就可以
*/
int Reverse(Seqlist *seq,int begin,int end)
{
    if (begin<0||begin>seq->length-1||end<begin||end>seq->length-1) return 0;
    //左右指针
    int left=begin,right=end;
    //缓存
    int tem;
    //这个条件很重要
    while((right!=left)&&(right>left))
    {
        tem=seq->data[right];
        seq->data[right]=seq->data[left];
        seq->data[left]=tem;
        right--;
        left++;
    }
    return 1;
}

/*
 * 将一长度为n的数组的前段k个元素保持原顺序移动到数组后段,要求数据不丢失,且其他元素的位置无所谓
 * 1 2 3 4 5 6 7 8 9 10 k=3 前k个逆序 
 * 3 2 1 4 5 6 7 8 9 10     整体逆序
 * 10 9 8 7 6 5 1 2 3 4     得到答案
**/

int Q2(Seqlist *seq,int k)
{
    return Reverse(seq,0,k)&&Reverse(seq,0,seq->length-1);;
}
/**
 * 数组循环左移p位
 * 1 2 3 4 5 6 7 8 9 10 k=3 前p个逆序 
 * 3 2 1 10 9 8 7 6 5 4     p-length-1逆序
 * 4 5 6 7 8 9 10 1 2 3     整体逆序
*/

int Q3(Seqlist *seq,int p)
{
     Reverse(seq,0,p)&&Reverse(seq,p+1,seq->length-1);
     Reverse(seq,0,9); 
     return 0;
}

#pragma endregion
#pragma region 王道顺序表大题

//从此往下4个题目都很相似,其思想就算顺序表边查找便删除
//也就是某些元素满足某一个条件需要删掉,设置一个计数器记录该元素的个数
//后面元素移动计数器个个数即可删除掉满足条件的元素
//最后别忘了length减去count

/**
 * 对于一个长度为n的顺序表x,编写一个时间复杂度为on,空间复杂度为o1的算法,该算法
 * 删除线性表中所有值为x的数据元素。
 * input: 1 2 3 4 3 5 8 6 3 4 1 2 4 3 5 4
 * output:1 2 4 5 8 6 4 1 2 4 5 4 
 * Test:
 * Seqlist wang;
    InitSeqlist(&wang);
    int data[]={1,2,3,4,3,5,8,6,3,4,1,2,4,3,5,4};
    InsertElements(&wang,data,sizeof(data)/sizeof(int));
    DeleteX(&wang,3);
    ShowSeqlist(wang);
*/
void DeleteX(Seqlist *seq,int x)
{
    int count=0;
    for (int i = 0; i < seq->length; i++)
    {
        if (seq->data[i]==x) 
        {
            count++;
            continue;
        }
        seq->data[i-count]=seq->data[i];
    }
    seq->length-=count;
}
/**
 * 从有序顺序表中删除其值在给定值s与t之间的(要求s<t)的所有元素,如果s或t不合理或者顺序表位空,则显示错误信息并退出
 * input: 1 2 3 4 5 6 7 8 9 10  s=3 t=7
 * output:1 2 3 7 8 9 10
 * test:
 * Seqlist wang;
    InitSeqlist(&wang);
    for (int i = 0; i < 10; i++)
    {
        InsertElement(&wang,i,i+1);
    }
    DeleteBetwenST(&wang,3,7);
    ShowSeqlist(wang);
*/
int DeleteBetwenST(Seqlist *seq ,int s,int t)
{
    if((s>t)||s==t||seq->length==0||s<1||t>seq->length) return -1;
    int count=0;
    for (int i = 0; i < seq->length; i++)
    {
        if (seq->data[i]>s&&seq->data[i]<t)
        {
            count++;
            continue;
        }
        seq->data[i-count]=seq->data[i];
    }
    seq->length-=count;
    return 1;
}
/**
 * 从顺序表中删除其值在st之间包含st要求s<t的所有元素,如果s或t不合理或顺序表为空,返回错误信息
 * s=3 t=5
 * input: 1 2 3 4 3 5 8 6 3 4 1 2 4 3 5 4
 * output: 1 2 8 6 1 2
 * test:
 *  Seqlist wang;
    InitSeqlist(&wang);
    int data[]={1,2,3,4,3,5,8,6,3,4,1,2,4,3,5,4};
    InsertElements(&wang,data,sizeof(data)/sizeof(int));
    DeleteST(&wang,3,5);
    ShowSeqlist(wang);
*/
int DeleteST(Seqlist *seq,int s,int t)
{
    if((s>t)||s==t||seq->length==0||s<1||t>seq->length) return -1;
    int count=0;
    for (int i = 0; i < seq->length; i++)
    {
        if ((seq->data[i]>s||seq->data[i]==s)&&(seq->data[i]<t||seq->data[i]==t))
        {
            count++;
            continue;
        }
        seq->data[i-count]=seq->data[i];
    }
    seq->length-=count;
    return 1;
}
/**
 * 从有序顺序表中删除所有其值重复的元素,使表中的所有元素均不相同
 * 
*/
int DeleteSameElement(Seqlist *seq)
{
    int count=0;
    for (int i = 0; i < seq->length; i++)
    {
        if (seq->data[i]==seq->data[i+1])
        {
            count++;
            continue;
        }
        seq->data[i-count]=seq->data[i];  
    }
    seq->length-=count;
}

//合并顺序表
/**
 * 将两个有序顺序表合并成一个新的有序顺序表,并有函数返回结果
 * 1 2 4 5 7 9
 * 4 8 10 12 14 22 31
 * 1 2 4 4 5 7 8 9 10 12 14 22 31 
 * test:
 * Seqlist wang,w1,w2;
    
    InitSeqlist(&wang);
    InitSeqlist(&w1);
    InitSeqlist(&w2);
    int a[6]={1,2,4,5,7,9};
    InsertElements(&w1,a,sizeof(a)/sizeof(int));
    int b[7]={4,8,10,12,14,22,31};
    InsertElements(&w2,b,sizeof(b)/sizeof(int));
    AddSeqList(&w1,&w2,&wang);
    ShowSeqlist(wang);
*/
int AddSeqList(Seqlist *src,Seqlist * dir,Seqlist * result)
{
    //没有空间可以容纳
    if((src->length+dir->length)>Maxsize) return -1;
    //设置两个指针分别指向顺序表12的开头
    int ps=0,pd=0,i=0;
    //当其中一个指针指向末尾则结束,不能往下继续
    //因为有一个++后越界
    while(ps!=(src->length)&&(pd!=dir->length))
    {
        if (src->data[ps]<dir->data[pd])
        {
            result->data[i]=src->data[ps];
            i++;ps++;
            result->length++;
            continue;
        }
        else
        {
            result->data[i]=dir->data[pd];
            pd++;i++;
            result->length++;
            continue;
        }
    }
    //不可能大于
    for (;ps < src->length;i++,ps++)
    {
        result->data[i]=src->data[ps];
        result->length++;
    }
    for (;pd < dir->length;i++,pd++)
    {
        result->data[i]=dir->data[pd];
        result->length++;
    }
    return 0;
}


/**
 * 线性表a1 a2 ... an 中元素递增且有序存储于计算机内部,要求设计一算法
 * 完成用最少的时间查找数值为x的元素,若找到则将其与其后继元素交换位置,若找不到
 * 则将其插入表中并使得表中元素仍递增有序。
 * 1 2 3 4 5 7 8 9 10 
*/
int Findx(Seqlist *seq,int x)
{
    int pos=0;
    for (int i = 0; i < seq->length; i++)
    {
        if (seq->data[i]==x)
        {
            //最后一个元素没有后继元素。
            if(i==seq->length-1) return -1;
            seq->data[i]=seq->data[i+1];
            seq->data[i+1]=x;
            return 1;
        }
        else if(seq->data[i]>x)
        {
            //没有空间容纳
            if (seq->length+1>Maxsize) return -1;       
            for (int j = seq->length;j>i-1; j--)
            {
                seq->data[j]=seq->data[j-1];
            }
            seq->data[i]=x;
            return 1;
        }
    }
    //x不再该序列范围内
    return -1;
}

int FindMiddleNum(Seqlist *src,Seqlist *dir)
{
    Seqlist result;
    InitSeqlist(&result);
    AddSeqList(src,dir,&result);
    if (result.length%2==0)
    {
        int i=(result.length)/2-1,j=result.length/2;
        return (result.data[i]+result.data[j])/2;
    }
    else
    {
        int i=(result.length+1)/2-1;
        return result.data[i];
    }    
}

//暂时不会
//2013.12题
int FindMainElement(Seqlist *seq);

int FindMissMinNum(Seqlist *seq,int n)
{
    int num=1;
    int count[n];
    for (int i = 0; i < n; i++)
    {
        count[i]=0;
    }
    for (int i = 0; i < seq->length; i++)
    {
        if (seq->data[i]>0&&seq->data[i]<n) count[seq->data[i]-1]=1;
    }
    int k=0;
    for (k = 0; k < n; k++)
    {
        if(count[k]==0) break;
    }
    return k+1;
}


#pragma endregion


int main()
{
    Seqlist seq;
    InitSeqlist(&seq);
    for (int i = 0; i < 5; i++)
    {
        InsertElement(&seq,i,i);
    }
    ShowSeqlist(seq);
    InsertElement(&seq,2,8);
    ShowSeqlist(seq);
    int x=DeleteElement(&seq,3);
    printf("be deletd x is %d\n",x);
    ShowSeqlist(seq);

    int pos=FindByContent(&seq,8);
    printf("x is positioned on %d\n",pos);

    printf("逆序前\n");
    ShowSeqlist(seq);
    Reverse(&seq,0,seq.length-1);
    printf("逆序后\n");
    ShowSeqlist(seq);

    printf("逆序前\n");
    ShowSeqlist(seq);
    Q2(&seq,2);

    Seqlist bigseq;
    InitSeqlist(&bigseq);
    for (int i = 0; i < 10; i++)
    {
        InsertElement(&bigseq,i,i+1);
    }
    printf("逆序前\n");
    ShowSeqlist(bigseq);
    Q3(&bigseq,3);
    printf("逆序后\n");
    ShowSeqlist(bigseq);

    Seqlist wang,w1,w2;
    
    InitSeqlist(&wang);
    
    int a[9]={1,2,3,4,5,7,8,9,10};
    InsertElements(&wang,a,sizeof(a)/sizeof(int));
    Findx(&wang,7);
    ShowSeqlist(wang);

    
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值