线性表(持续更新中)

constants.h

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1//不可实行的
#define OVERFLOW -2//溢出

typedef int Status;

线性表的顺序存储结构

Sqlist.h

#include "constants.h"

#define LIST_INIT_SIZE 20 //顺序表存储空间的初始分配量
#define LISTINCREMENT 5   //顺序表存储空间的分配增量

typedef int ElemType;

typedef struct
{
    ElemType *elem; //存储空间的基地址
    int length;     //顺序表的当前长度
    int listsize;   //数组存储空间的长度
} Sqlist;

Status InitList(Sqlist &L); //构造一个空的线性表L

Status ListEmpty(Sqlist L); //判断线性表L是否是空表,若是,则返回TRUE,否则返回FALSE

int ListLength(Sqlist L); //返回线性表L的长度

Status GetElem(Sqlist L, int i, ElemType &e); //用e返回线性表L的第i个数据元素的值

int LocateElem(Sqlist L, ElemType e, Status (*compare)(ElemType, ElemType)); //在线性表L中查找第一个和元素e满足compare关系的元素,若找到则返回其位序;否则返回0

Status PriorElem(Sqlist L, ElemType e, ElemType &pre_e); //用pre_e返回线性表L中元素e的直接前驱

Status NextElem(Sqlist L, ElemType e, ElemType &next_e); //用next_e返回线性表L中元素e的直接后继

Status ListInsert(Sqlist &L, int i, ElemType e); //将数据元素e插入到线性表L的第i个数据元素之前

Status ListDelete(Sqlist &L, int i, ElemType &e); //删除线性表L的第i个数据元素,并将其值用e返回

Status ListTraverse(Sqlist L, Status (*visit)(ElemType)); //依次对线性表L中的每个元素调用visit进行访问

Status ClearList(Sqlist &L); //重置线性表L为空表

Status DestroyList(Sqlist &L); //销毁线性表L,可能的话释放其空间

Status adjust(Sqlist &L);

Status compare_equal(ElemType a, ElemType b);

Status visit_read(ElemType a);

void MergeList_Sq(Sqlist L1, Sqlist L2, Sqlist &l0);

Sqlist.cpp

#include "sqlist.h"
#include<stdlib.h>
#include<stdio.h>

Status InitList(Sqlist &L)
{
    L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));
    if (!L.elem)
        exit(OVERFLOW);
    L.length = 0;
    L.listsize = LIST_INIT_SIZE;
    return OK;
}

Status ListEmpty(Sqlist L)
{
    if (!L.length)
        return TRUE;
    else
        return FALSE;
}

int ListLength(Sqlist L)
{
    return L.length;
}

Status GetElem(Sqlist L, int i, ElemType &e)
{
    if (i > 0 && i <= L.length)
    {
        e = L.elem[i - 1];
        return OK;
    }
    else
        return ERROR;
}

//函数做参数 用指针来表达(与数组类似)
//在调用时参数只需要写函数名,在使用时也只需要写函数名
int LocateElem(Sqlist L, ElemType e, Status (*compare)(ElemType, ElemType))
{
    int i = 1;
    ElemType *p = L.elem;
    /* 前缀递增递减和*优先级相同,从右到左;
        后缀递增递减比前缀优先级高,从左到右。 */
    while (i <= L.length && !compare(e, *p++))
        i++;
    if (i > L.length)
        return 0;
    else
        return i;
}

Status PriorElem(Sqlist L, ElemType e, ElemType &pre_e)
{
    int weixu = LocateElem(L, e, compare_equal);
    if (weixu > 1)
    {
        pre_e = L.elem[weixu - 2];
        return OK;
    }
    else
        return ERROR;
}

Status NextElem(Sqlist L, ElemType e, ElemType &next_e)
{
    int weixu = LocateElem(L, e, compare_equal);
    if (weixu > 0 && weixu < L.length)
    {
        next_e = L.elem[weixu];
        return OK;
    }
    else
        return ERROR;
}

//把元素e插入到第i个元素前面 <==> 让元素e成为顺序表中的第i个元素
Status ListInsert(Sqlist &L, int i, ElemType e)
{
    if (i < 1 || i > L.length + 1)
        return ERROR;
    else
    {
        if (L.length == L.listsize)
            if (!adjust(L))
                exit(OVERFLOW);
        ElemType *p = L.elem + L.length - 1;
        while (p != L.elem + i - 2)
        {
            *(p + 1) = *p;
            p--;
        }
        *(p + 1) = e;
        /* ElemType *p = &L.elem[i - 1], *q;
        for (q = &L.elem[L.length - 1]; q >= p; q--)
            *(q + 1) = *q;
        *q = e; */
        L.length++;
        return OK;
    }
}

//在ListInsert和ListDelete函数的最后一定要记得更新L。length的值
Status ListDelete(Sqlist &L, int i, ElemType &e)
{
    if (i < 1 || i > L.length)
        return ERROR;
    else
    {
        e = L.elem[i - 1];
        ElemType *p = &L.elem[i], *q = &L.elem[L.length - 1];
        for (; p <= q; p++)
            *(p - 1) = *p;
        /* ElemType *p = L.elem + i - 1, *q = L.elem + L.length - 1;
        e = *p;
        for (p++; p <= q; p++)
            *(p + 1) = *p; */
        L.length--;
        return OK;
    }
}

Status ListTraverse(Sqlist L, Status (*visit)(ElemType))
{
    ElemType *p, *q = L.elem + L.length - 1;
    for (p = L.elem; p <= q; p++)
        if (!visit(*p))
            return ERROR;
    return OK;
}

Status ClearList(Sqlist &L)
{
    L.length = 0;
    return OK;
}

//free函数调用之前需要加一个if句来判断将要free的指针是否指向某一块内存空间,free之后赋值为NULL
Status DestroyList(Sqlist &L)
{
    if (L.elem)
        free(L.elem);
    L.elem = NULL;
    return OK;
}

/* 原型:extern void *realloc(void *mem_address, unsigned int newsize);
语法:指针名=(数据类型*)realloc(要改变内存大小的指针名,新的大小)。
     //新的大小若小于原来的大小,原数据的末尾可能丢失(被其他使用内存的数据覆盖等)
头文件:#include <stdlib.h> 有些编译器需要#include <malloc.h>,在TC2.0中可以使用alloc.h头文件
功能:先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,如果空间不够,先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域(注意:原来指针是自动释放,不需要使用free),同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。
返回值:如果重新分配成功则返回指向被分配内存的指针,否则返回空指针NULL。
注意:这里原始内存中的数据还是保持不变的。当内存不再使用时,应使用free()函数将内存块释放。 */
Status adjust(Sqlist &L)
{
    L.elem = (ElemType *)realloc(L.elem, (LIST_INIT_SIZE + LISTINCREMENT) * sizeof(ElemType));
    if (!L.elem)
        exit(OVERFLOW);
    else
    {
        L.listsize += LISTINCREMENT;
        return OK;
    }
}

Status compare_equal(ElemType a, ElemType b)
{
    return a == b ? TRUE : FALSE;
}

Status visit_read(ElemType a)
{
    printf("%d\n", a);
    return OK;
}

void MergeList_Sq(Sqlist L1, Sqlist L2, Sqlist &L0)
{
    ElemType *p1 = L1.elem, *p2 = L2.elem;
    L0.listsize = L0.length = L1.length + L2.length;
    ElemType *p0 = (ElemType*)malloc(L0.length*sizeof(ElemType));
    L0.elem = p0;
    ElemType *p1_last = L1.elem + L1.length - 1, *p2_last = L2.elem + L2.length - 1;
    while (p1 <= p1_last && p2 <= p2_last)
    {
        if (*p1 < *p2)
            *p0++ = *p1++;
        else
            *p0++ = *p2++;
    }
    while (p1 <= p1_last)
        *p0++ = *p1++;
    while (p2 <= p2_last)
        *p0++ = *p2++;
    /*    L0.elem = (ElemType *)malloc((L1.length + L2.length) * sizeof(ElemType));
    L0.length = L1.length + L2.length;
    L0.listsize = L0.length;
    int i = 0, j = 0, k = 0;
    while (i < L1.length && j < L2.length)
    {
        if (L1.elem[i] < L2.elem[j])
            L0.elem[k++] = L1.elem[i++];
        else
            L0.elem[k++] = L2.elem[j++];
    }
    if (i == L1.length)
        while (j < L2.length)
            L0.elem[k++] = L2.elem[j++];
    else
        while (i < L1.length)
            L0.elem[k++] = L1.elem[i++]; */
}

线性表的链式存储结构

单链表(最简单)

LinkList.h

#include "constants.h"

typedef int ElemType;

//Attention: *结构体类型要有名字   *typedef之后的别名可以和原名一样
typedef struct LNode
{
    ElemType data;      //数据域
    struct LNode *next; //指针域
} LNode, *LinkList;

Status InitList(LinkList &L); //构造一个空的线性表L

Status ListEmpty(LinkList L); //判断线性表L是否是空表,若是,则返回TRUE,否则返回FALSE

int ListLength(LinkList L); //返回线性表L的长度

Status GetElem(LinkList L, int i, ElemType &e); //用e返回线性表L的第i个数据元素的值

LNode *LocateElem(LinkList L, ElemType e, Status (*compare)(ElemType, ElemType)); //在线性表L中查找第一个和元素e满足compare关系的元素,若找到则返回其位序;否则返回0

Status PriorElem(LinkList L, ElemType e, ElemType &pre_e); //用pre_e返回线性表L中元素e的直接前驱

Status NextElem(LinkList L, ElemType e, ElemType &next_e); //用next_e返回线性表L中元素e的直接后继

Status ListInsert(LinkList &L, int i, ElemType e); //将数据元素e插入到线性表L的第i个数据元素之前

Status ListDelete(LinkList L, int i, ElemType &e); //删除线性表L的第i个数据元素,并将其值用e返回

Status ListTraverse(LinkList L, Status (*visit)(ElemType)); //依次对线性表L中的每个元素调用visit进行访问

Status ClearList(LinkList &L); //重置线性表L为空表

Status DestroyList(LinkList &L); //销毁线性表L,可能的话释放其空间

Status compare_equal(ElemType a, ElemType b);

Status visit_read(ElemType a);

void MergeList_LinkList(LinkList L1, LinkList L2, LinkList &l0);

void CreateList_backward(LinkList &L, int n);//逆向建立n个元素的单链表

LinkList.cpp

#include "Linklist.h"
#include <stdio.h>
#include <stdlib.h>

Status InitList(LinkList &L) //O(1)
{
    L = (LinkList)malloc(sizeof(LNode));
    if (!L)
        exit(OVERFLOW);
    L->next = NULL;
    return OK;
}

Status ListEmpty(LinkList L) //O(1)
{
    /* return L->next ? TRUE : FALSE; */
    if (!L->next)
        return TRUE;
    else
        return FALSE;
}

int ListLength(LinkList L) //O(n)
{
    LNode *p = L->next;
    int length = 0;
    while (p)
    {
        length++;
        p = p->next;
    }
    return length;
}

Status GetElem(LinkList L, int i, ElemType &e) //O(n)
{
    /*   if (i < 1 || i > ListLength(L))
        return ERROR;
    LNode *p = L;
    int j;
    for (j = 0; j < i; j++)
        p = p->next;
    e = p->data;
    return OK; */
    int j = 1;
    LNode *p = L->next;
    while (p && j < i)
    {
        p = p->next;
        j++;
    }
    if (!p || j > i)
        return ERROR;
    else
    {
        e = p->data;
        return OK;
    }
}

/* 定位函数不准返回ERROR 因为ERROR是int类型 不是LNode*类型
找到即返回该结点的地址 找不到即返回NULL */
LNode *LocateElem(LinkList L, ElemType e, Status (*compare)(ElemType, ElemType)) //O(n)
{
    LNode *p = L->next;
    while (p && !compare(e, p->data))
        p = p->next;
    return p;
}

Status PriorElem(LinkList L, ElemType e, ElemType &pre_e)
{
    LNode *p = L->next;
    while (p && p->next->data != e)
        p = p->next;
    if (!p)
        return ERROR;
    else
    {
        pre_e = p->data;
        return OK;
    }
}

Status NextElem(LinkList L, ElemType e, ElemType &next_e)
{
    LNode *p = LocateElem(L, e, compare_equal);
    if (!p && !p->next)
        return ERROR;
    else
    {
        next_e = p->data;
        return OK;
    }
}

Status ListInsert(LinkList &L, int i, ElemType e)
{
    if (i < 1 || i > ListLength(L) + 1)
        return ERROR;
    else
    {
        LNode *p=L;
        int j;
        for (j = 0; j < i - 1; j++)
            p = p->next;
        LNode *p0 = (LNode *)malloc(sizeof(LNode));
        if (!p0)
            exit(OVERFLOW);
        else
        {
            p0->data = e;
            p0->next = p->next;
            p->next = p0;
            return OK;
        }
    }
}

void CreateList_backward(LinkList &L, int n)
{
    InitList(L);
    while (n--)
    {
    	int x;
    	scanf("%d",&x);
        ListInsert(L, 1, x);
    }
}

//删除过后的结点需要被释放内存
Status ListDelete(LinkList &L, int i, ElemType &e)
{
    if (i < 1 || i > ListLength(L))
        return ERROR;
    else
    {
        LNode *p = L;
        int j;
        for (j = 0; j < i - 1; j++)
            p = p->next;
        e = p->next->data;
        free(p->next);
        p->next = p->next->next;
        return OK;
    }
}

Status ListTraverse(LinkList L, Status (*visit)(ElemType))
{
    LNode *p = L->next;
    while (p)
    {
        if (!visit(p->data))
            return ERROR;
        p = p->next;
    }
    return OK;
}

//clear函数思想:不断free(L->next)
Status ClearList(LinkList &L)
{
    LNode *p;
    for (p = L->next; p; p = L->next)
    {
        L->next = p->next;
        free(p);
    }
    return OK;
}

Status DestroyList(LinkList &L)
{
    while (L)
    {
        LNode *p = L->next;
        free(L);
        L = p;
    }
    return OK;
}

Status compare_equal(ElemType a, ElemType b)
{
    return a == b ? TRUE : FALSE;
}

Status visit_read(ElemType a)
{
    printf("%d\n", a);
    return OK;
}

void MergeList_LinkList(LinkList L1, LinkList L2, LinkList &L0)
{
    LNode *p1 = L1->next, *p2 = L2->next, *p = L0;
    while (p1 && p2)
    {
        LNode *p0 = (LNode *)malloc(sizeof(LNode));
        p->next = p0;
        p0->next = NULL;
        if (p1->data < p2->data)
        {
            p0->data = p1->data;
            p1 = p1->next;
        }
        else
        {
            p0->data = p2->data;
            p2 = p2->next;
        }
        p = p->next;
    }
    while (p1)
    {
        LNode *p0 = (LNode *)malloc(sizeof(LNode));
        p->next = p0;
        p0->next = NULL;
        p0->data = p1->data;
        p1 = p1->next;
        p = p->next;
    }
    while (p2)
    {
        LNode *p0 = (LNode *)malloc(sizeof(LNode));
        p->next = p0;
        p0->next = NULL;
        p0->data = p2->data;
        p2 = p2->next;
        p = p->next;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

罗马尼亚硬拉

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

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

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

打赏作者

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

抵扣说明:

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

余额充值