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("\n");
}

二、最值

给定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;
    }
}
posted @ 2020-06-23 09:05  衍射  阅读(227)  评论(0编辑  收藏  举报