1.数据结构,顺序表算法实现

#include <stdio.h>
#include <stdlib.h>
#define  INIT_SIZE 100
#define  INCRE_SIZE 10
typedef int ElemType;
typedef struct SqList  //1.顺序表的动态存储
{
    ElemType *pList;
    int length;//表长
    int listsize;//顺序表大小
} SqList;
void initial(SqList &L) //初始化链表
{
    L.pList = (int *)malloc(sizeof(int) * INIT_SIZE);
    L.length = 0 ;
    L.listsize = 100;
}

void deleteIthELem(SqList &L,int ith,int &e) //2.删除第ith个元素
{
    if(ith <= L.length)
    {
        e = L.pList[ith-1];
        for(int curIndex = ith; curIndex < L.length; curIndex++)
        {
            L.pList[curIndex-1] = L.pList[curIndex];
        }
    }
    --L.length;
    printf("deleted elem is %d\n",e);
}

void insert(SqList &L,int ith,int elem) //3.在第i个元素前插入e
{
    if(ith>=1 && ith<=L.length && L.length<L.listsize)  //判断插入合法性
    {
        for(int i = L.length; i>=ith; i--)
        {
            L.pList[i] = L.pList[i-1];
        }
        L.pList[ith-1]= elem; //插入元素
    }
    printf("insert completed!\n");
    printf("insert elem is %d\n",L.pList[ith-1]);
    L.length++;
}

void test(SqList &L)  //赋值用来测试
{
    printf("顺序表初始化:");
    for(int i =0; i<5; i++)
    {
        L.pList[i] = i;
        //  printf("%d",L.pList[i]);
    }
    for(int i =9; i>=5; i--)
    {
        L.pList[i] = 10-i;
        //  printf("%d",L.pList[i]);
    }
    for(int i =0;i<10;i++){
        printf("%d ",L.pList[i]);
    }
    printf("\n");
    L.length = 10;
}

void view(SqList L){
   printf("\nview:");
    for(int i=0;i<L.length;i++){
        printf("%d ",L.pList[i]);
    }
    printf("\n");
}

void delMinElem(SqList &L) //4.删除最小元素
{
    int minIndex = 0;  //记录最小节点元素的索引
    for(int i =1; i<L.length; i++)
    {
        if(L.pList[i]<L.pList[minIndex])
        {
            minIndex = i;
        }
    }
    printf("最小元素的索引为:%d\n",minIndex);
    L.pList[minIndex] = L.pList[L.length-1];
    L.length--;
}

void deleteElems_t(int s,int t,SqList &L)  //5.删除元素值s_t之间的元素
{
    int curLength = 0;
    for(int curindex = 0 ; curindex<L.length; curindex++)
    {
        int e  = L.pList[curindex];
        if(e<s || e>t)  //直接在原顺序表的位置进行操作
        {
            L.pList[curLength] = e;
            ++curLength; //也可以单独开空间进行操作
        }
    }
    L.length = curLength;
}

/*6.
在非递减的顺序表中删除[s,t]的元素
思路:先从前往后找最后一个小于s的元素
再从后往前找第一个大于t的元素
*/
void deleteElems_t2(int s,int t,SqList &L)
{
    int curLength = 0;
    int curIndex = 0;
    while(curIndex<L.length)
    {
        if(L.pList[curIndex] >= s)
        {
            break; //找到第一个>=s的元素
        }
        curIndex++;
    }
    curLength = curIndex;//更新表长
    curIndex  = L.length - 1;
    while(curIndex >=0)
    {
        if(L.pList[curIndex] <= t)
        {
            break;
        }
        curIndex--;
    }
    ++curIndex;//指向第一个大于t的元素
    while(curIndex < L.length)
    {
        L.pList[curLength] = L.pList[curIndex];
        ++curIndex;
        ++curLength;
    }
    L.length = curLength; //最后更新表长
}

/*7.删除非递减顺序表中的重复元素*/
void deleteElems_t3(SqList &L)
{
    int curLength = 0;
    for(int i = 0; i<L.length; i++)
    {
        int e = L.pList[i];
        if(curLength == 0)
        {
            L.pList[curLength] = e;//新表中无元素时直接追加
            curLength++;
        }
        if(e != L.pList[curLength-1])  //与新表表尾元素不同,
        {
            L.pList[curLength] = e;
            curLength ++;
        }
    }
    L.length = curLength;
}


/*8.合并两个顺序表,A是升序,B是降序,两个
个表中都不存在相同的元素
A表中有 m个元素,B表中有 n个元素
*/
//8.1 两个表和并存在C中(单独开m+n个存储空间)
void combine_to_c(SqList &La,SqList &Lb,SqList &Lc)
{
    Lc.length = La.length + Lb.length; //合并后的新表长度
    //申请Lc.length 个长度存储单元,并用p指向
    Lc.pList = (int *)malloc(sizeof(int)*Lc.length);
    int curLength = 0;//新表中的元素
    int IndexLa = 0; //指向A表第一个元素
    int IndexLb = Lb.length -1 ;//指向B表最后一个元素
    while(IndexLa<La.length && IndexLb >= 0 ){
        if(La.pList[IndexLa] < Lb.pList[IndexLb]){
            //La中的元素更小,追加到新表
            Lc.pList[curLength] = La.pList[IndexLa];
            curLength++;
            IndexLa++;//指向下一个元素
        }else{
            Lc.pList[curLength] = Lb.pList[IndexLb];
            curLength++;
            IndexLb--;
        }
    }
    //如果A表中还有剩余元素,则说明B表中最大的元素都比
    //此时A表中最小的元素小,所以直接将A表中剩余元素插入即可
    while(IndexLa < La.length){
        Lc.pList[curLength] = La.pList[IndexLa];
        IndexLa ++;
        curLength++;
    }
    //如果B表还有剩余则说明B表中,此时最小的元素都比A表最大的元素大
    //所以直接插入即可
    while(IndexLb < Lb.length){
        Lc.pList[curLength] = Lb.pList[IndexLb];
        curLength++;
        IndexLb--;
    }
    //此时合并完成,释放掉A和B两个表中的存储空间
    free(La.pList);
    La.length = 0;
    La.pList  =0;
    free(Lb.pList);
    Lb.length = 0;
    Lb.listsize  =0 ;
}

//8.2 A表中有m+n个存储空间,合并到A表中
void combine_to_A(SqList &La,SqList &Lb)
{
    int curLength = 0;//新表表长
    int IndexLa = La.length-1;//指向A表中最大元素
    int IndexLb = 0;//指向B表中最大元素

    while(IndexLa>=0 && IndexLb < Lb.length){
        if(La.pList[IndexLa] > Lb.pList[IndexLb]){
            La.pList[La.listsize-curLength-1] = La.pList[IndexLa];
            curLength++;
            IndexLa--;
        }else{
            La.pList[La.listsize-curLength-1] = La.pList[IndexLb];
            curLength++;
            IndexLb++;
        }
    }

    //如果A表中还有元素剩余
    if(IndexLa >=0 ){
        La.pList[La.listsize-curLength-1] = La.pList[IndexLa];
        ++curLength;
        --IndexLa;
    }
    //如果B表中还有元素剩余
    if(IndexLb < Lb.length){
        La.pList[La.listsize-curLength-1] = Lb.pList[IndexLb];
        ++curLength;
        ++IndexLb;
    }

    //更新表长
    La.length = curLength;
    Lb.length = 0;
}

//8.3 A表中前r个元素递增,后面n-r个元素递减,使A递增
void sort_BA(SqList &La,int k)
{
    int curIndex = k;//指向第k个元素,降序的第一个元素
    while(curIndex < La.length){
        int  e  = La.pList[curIndex]; //保存待插入值
        int i = curIndex - 1;
        while(i>=0 && La.pList[i] > e){
            La.pList[i+1] = La.pList[i];
            --i;
        }//找到待插入位置
        La.pList[i+1] = e;
        ++curIndex;//指向下一个待插入元素
    }
}

//9.两个升序的非空集合,按照顺序表的方式存储,求交集
//同一个序列中无相同元素,因为是集合(理解)
void intersect(SqList &La,SqList &Lb){
    int curLength = 0 ;//记录新表长度
    int IndexLa = 0;
    int IndexLb = 0;
    while(IndexLa < La.length && IndexLb < Lb.length){
        if(La.pList[IndexLa] < Lb.pList[IndexLb]){
            IndexLa ++;
        }else if(Lb.pList[IndexLb] < La.pList[IndexLa]){
            IndexLb ++;
        }else{//有相同元素,将新元素追加到表尾
            La.pList[curLength] = La.pList[IndexLa];
            curLength++;
            IndexLa++;
            IndexLb++;
        }
    }
    La.length = curLength;
}


//10.两个非空集合,分别按照顺序表升序的方式进行存储
//A-B 差集
void except(SqList &La,SqList &Lb)
{
    int curLength = 0;
    int IndexLa =0;
    int IndexLb = 0;
    while(IndexLa < La.length && IndexLb < Lb.length)
    {
        if(La.pList[IndexLa] < Lb.pList[IndexLb]){
            La.pList[curLength] = La.pList[IndexLa];
            curLength++;
            IndexLa++;
        }else if(La.pList[IndexLa]> Lb.pList[IndexLb]){
            IndexLb++;
        }else{//两者相等的情况
            IndexLa++;
            IndexLb++;
        }
    }
    La.length = curLength;//更新表长
}

//11.设计算法逆置顺序表L
/*
    分析:
    用两个指针分别从两个方向开始扫描
    交换后,再分别下移一个位置,最终完成扫描
*/
void reverse(SqList &Lm,int low,int high)
{
    int low = 0;//整个逆置
    int high = L.length-1;
    while(low<high){
        int e = L.pList[high];
        L.pList[high] = L.pList[low];
        L.pList[low] = e;
        low++;
        high--;
    }
}


//12.将序列L循环左移动r(重点,记忆,四颗星)
void ROL(SqList &L,int r){
    reverse(L,0,L.length-1);
    reverse(L,0,L.length-1-r);
    reverse(L,L.length-r,L.length-1);
}
int main()
{
    SqList s;//创建顺序表
    initial(s); //进行初始化
    test(s);
    int x;
    deleteIthELem(s,3,x);
    insert(s,3,x);
    delMinElem(s);
    test(s);
    deleteElems_t3(s);//删除重复元素
    view(s);

    test(s);
    sort_BA(s,5);
    view(s);
    return 0;
}

posted @ 2023-08-25 17:14  TCcjx  阅读(7)  评论(0编辑  收藏  举报