• 5.顺序表和链表的最值,逆置和归并有序表


    一、顺序表和链表的数据结构。

    顺序表:

    #include <malloc.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #define MaxSize 50
    #define ElemType int
    // 顺序表
    typedef struct 
    {
        ElemType *data;
        int length;
    }SqList;
    
    void InitList(SqList *&L,ElemType a[],int n)
    {
        L = (SqList *)malloc(sizeof(SqList));
        //动态声明数组空间
        L->data = (ElemType *)malloc(sizeof(ElemType)*MaxSize);
        for (int i=0;i<n;i++)
            L->data[i]=a[i];
        L->length=n;
    }
    
    //前插
    bool ListInsert(SqList *&L, int i, ElemType e){
        //判断是否超过边界
        if(i < 1 || i > L->length + 1)
            return false;
        //判断数组有没有满
        if(L->length >= MaxSize)
            return false;
        //每个数据元素都往后移
        for(int j = L->length; j >= i; j--)
            L->data[j] = L->data[j-1];
        L->data[i-1] = e;
        L->length++;
        return true;
    }
    
    //删除
    bool ListDelete(SqList *&L, int i, ElemType &e){
        //判断是否超过边界
        if(i < 1 || i > L->length)
            return false;
        e = L->data[i-1];
        for(int j = i; j < L->length; j++)
            L->data[j-1] = L->data[j];
        L->length--;
        return true;
    }
    
    //按值查找,返回顺序表的表号
    int LocateElem(SqList L, ElemType e){
        int i;
        for(i = 0; i<L.length; i++){
            if(L.data[i] == e)
                return i+1;
        }
        return 0;//查找失败
    }
    
    //打印顺序表
    void printSqList(SqList L){
        for(int i = 0; i<L.length; i++){
            printf("%d ",L.data[i]);
        }
    }
    
    void DestroyList(SqList *&L)
    {
        free(L->data);
        free(L);
    }
    

    链表:

    #include <malloc.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #define ElemType int
    
    typedef struct LNode  
    {
        ElemType data;
        struct LNode *next;
    } LinkNode; 
    
    //头插法
    void CreateListF(LinkNode *&L,ElemType a[],int n){
        L=(LinkNode *)malloc(sizeof(LinkNode));
        L->next=NULL;
        LinkNode *s;
        for(int i =0; i < n; i++){
            s=(LinkNode *)malloc(sizeof(LinkNode));
            s->data = a[i];
            s->next = L->next;
            L->next = s;
        }
    }
    
    //尾插法
    void CreateListR(LinkNode *&L,ElemType a[],int n){
        L=(LinkNode *)malloc(sizeof(LinkNode));
        L->next=NULL;
        LinkNode *s, *r;
        r = L;
        for(int i =0; i < n; i++){
            s=(LinkNode *)malloc(sizeof(LinkNode));
            s->data = a[i];
            s->next = r->next;
            r->next = s;
            r = r->next;
        }
    }
    
    //按序号查找
    LinkNode *GetElem(LinkNode *&L, int i){
        int j = 1;
        LinkNode *p = L;
        if(i == 0)
            return L;//返回头节点
        if(i<1)
            return NULL;
        while(p && j<i){ //p是否为NULL判断是否到链表尾
            p = p->next;
            j++;
        }
        return p;
    }
    
    bool ListInsert(LinkNode *&L,int i,ElemType e)
    {
        LinkNode* p = GetElem(L,i-1);//获取第i-1号节点
        if(p==NULL)
            return false;
        LinkNode *s;
        s->data = e;
        s->next = p->next;
        p->next = s;
    }
    bool ListDelete(LinkNode *&L,int i,ElemType &e)
    {
        LinkNode* pre = GetElem(L,i-1);//获取第i-1号节点
        LinkNode* p = pre->next;//第i号
        if(pre == NULL)
            return false;
        e = p->data;
        pre->next = p->next;
        free(p);
        return true;
    }
    void DestroyList(LinkNode *&L)
    {
        LinkNode *pre=L,*p=pre->next;
        while (p!=NULL)
        {   free(pre);
            pre=p;
            p=pre->next;
        }
        free(pre);
    }
    
    void DispList(LinkNode *L)
    {
        LinkNode *p=L->next;
        while (p!=NULL)
        {   printf("%d ",p->data);
            p=p->next;
        }
        printf("
    ");
    }
    

    二、最值

    给定L = {3,1,5,9,2},求其中的最大值,最小值

    2.1 使用顺序表

    //求数组最小值,最大值
    void getMaxAndMin(SqList *&L, ElemType &_max, ElemType &_min){
        _max = _min = L->data[0];
        for(int i = 0; i < L->length; i++){
            if(L->data[i] >_max)
                _max = L->data[i];
            if(L->data[i] < _min)
                _min = L->data[i];
        }
    }
    

    2.2 使用链表

    //求 最小值,最大值
    void getMaxAndMin(LinkNode *&L, ElemType &_max, ElemType &_min){
        LinkNode *p = L->next;
        if(p==NULL)
            return;
        _max = _min = p->data;
        while(p!=NULL){
            if(p->data>_max)
                _max = p->data;
            if(p->data<_min)
                _min = p->data;
            p = p->next;
        }
    }
    

    三、逆置

    L = {3,1,5,9,2},逆置后成{2,9,5,1,3}

    3.1 顺序表的逆置

    具体的思路为:用i和j代表数组两端的下标,然后对换L[i]和L[j],i++, j–,直到i>=j

    //顺序表的逆置(从两边向中间靠,两边的元素互换)
    void ListReverse(SqList *&L){
        int i = 0, j = L->length-1;
        while(i <= j){
            ElemType n = L->data[i];
            L->data[i] = L->data[j];
            L->data[j] = n;
            i++;
            j--;
        }
    }
    

    3.2 链表的逆置

    图片

    将所有数据节点依次移动到尾节点之后:

    //转置
    void ListReverse(LinkNode *&L){
        LinkNode *r = L;
        // 将r设为尾节点
        while(r->next!=NULL){
            r = r->next; 
        }
        LinkNode *p = L->next;
        while (L->next != r)
        {
            //将p移动到r后方一位
            L->next = p->next;
            p->next = r->next;
            r->next = p;
    
            p = L->next;
        }
    }
    

    四、归并(前提:有序的表)

    L1 = {1,2,3,5}, L2={4,6,7,8},合并两数组为L3={1,2,3,4,5,6,7,8}

    4.1 顺序表实现归并有序表

    首先假定输入的顺序表是有序的,对两个顺序表从头开始比较,将较小的元素插入新表种,然后往下遍历,直至所有元素都插入新表

    图片

    //归并有序表(假定输入的两个顺序表都是有序的)
    void ListMerge(SqList *&L1, SqList *&L2, SqList *&L3){
        int i =0 , j=0 , z= 0;//i为L1下标,j为L2下标,z为L3下标
        int len1 = L1->length;
        int len2 = L2->length;
        for(;i<len1 && j<len2; z++){
            if(L1->data[i] < L2->data[j])
                L3->data[z] = L1->data[i++];
            else
                L3->data[z] = L2->data[j++];
        }
        while (i<len1)
        {
            L3->data[z++] = L1->data[i++];
        }
        while (j<len2)
        {
            L3->data[z++] = L2->data[j++];
        }
        L3->length = len1+len2;
    }
    

    4.2 链表实现归并有序表

    void ListMerge(LinkNode *&L1, LinkNode *&L2, LinkNode *&L3){
        LinkNode *p1 = L1->next, *p2 = L2->next, *p3 = L3;
        for(;p1!=NULL && p2!=NULL;p3 = p3->next){
            if(p1->data<p2->data){
                LinkNode *temp = (LinkNode*)malloc(sizeof(LinkNode));
                temp->data = p1->data;
                p3->next = temp;
                temp->next = NULL;
                p1=p1->next;
            }
            else{
                LinkNode *temp = (LinkNode*)malloc(sizeof(LinkNode));
                temp->data = p2->data;
                p3->next = temp;
                temp->next = NULL;
                p2=p2->next;
            }
        }
        while (p1!=NULL)//L1还没全部插入L3
        {
            LinkNode *temp = (LinkNode*)malloc(sizeof(LinkNode));
            temp->data = p1->data;
            p3->next = temp;
            temp->next = NULL;
            p1 = p1->next;
            p3=p3->next;
        }
        while (p2!=NULL)//L1还没全部插入L3
        {
            LinkNode *temp = (LinkNode*)malloc(sizeof(LinkNode));
            temp->data = p2->data;
            p3->next = temp;
            temp->next = NULL;
            p2 = p2->next;
            p3=p3->next;
        }
    }
    
  • 相关阅读:
    十大经典排序算法最强总结(含Java、Python码实现)
    数据库查询优化的12种方式
    开发环境、测试环境、预发布环境、生产环境的区别
    阅站无数的我,只推荐下面这些让你起飞的
    访问控制符
    继承的意义
    数组继承的意义
    java 俄罗斯方块
    类和面向对象
    随机生成数组游戏
  • 原文地址:https://www.cnblogs.com/theory/p/13338749.html
Copyright © 2020-2023  润新知