第二章、线性表

    第二章:线性表整理代码

MyList.h

/* * MyList.h * * Created on: 2016.11.12 * Author: Jack Cui */

/* *顺序存取和随机存取的区别: *顺序存取:就是存取第N个数据时,必须先访问前(N-1)个数据 (list) *随机存取:就是存取第N个数据时,不需要访问前(N-1)个数据,直接就可以对第N个数据操作 (array) */

#ifndef MYLIST_H_
#define MYLIST_H_

#include <iostream>
#include <stdlib.h>
#include <stdio.h>

using namespace std;

//函数结果状态代码
#define TRUE        1   
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE  -1      //不可行
#define OVERFLOW    -2      //溢出

//Status是函数的类型,其值是函数结果状态代码
typedef int Status;
//ElemType是某个确定的、将由用户自行定义的、含某个关系运算的数据对象
typedef int ElemType;

/**********线性表的动态分配顺序存储结构**********/
#define SQ_LIST_INIT_SIZE 50        //线性表存储空间的初始分配量
#define SQ_LISTINCREAMENT 10        //线性表存储空间的分配增量

typedef struct{
    ElemType *elem;         //存储空间基址
    int length;             //当前长度
    int listSize;           //当前分配的存储空间(以sizeof(ElemTpe)为单位)
}SqList;                    //顺序存储结构或顺序映像(sequential mapping)

void SqListTest();                  //顺序线性表测试函数
Status isEmpty(SqList *L);          //判断顺序线性表是否为空 
Status InitList_Sq(SqList *L);      //顺序线性表初始化函数
Status ListInsert_Sq(SqList *L, int pos, ElemType insert_elem);
                                    //顺序线性表插入元素实现函数
Status ListDelete_Sq(SqList *L, int pos, ElemType &delete_elem);                        
                                    //顺序线性表删除元素实现函数
Status LocateElem_Sq(SqList *L, ElemType e);                                    
                                    //顺序线性表元素查找
void MergeList_Sq(SqList *, SqList *Lb, SqList &Lc);                
                                    //顺序线性表的合并函数

/**********线性表的单链表存储结构**********/
typedef struct LNode{
    ElemType data;
    struct LNode *next;
}LNode, *LinkList;

//单链表获得i位置的值
Status GetElem_L(LinkList L, int i, ElemType &e);               
//单链表删除i位置元素
Status ListDelete_L(LinkList &L, int i, ElemType &e);           
//单链表在第i位置插入元素e
Status ListInsert_L(LinkList &L, int i, ElemType e);            
//逆序创建单链表
void CreateList_L(LinkList &L, int n);                          
//合并单链表
void MergeList_L(LinkList &La, LinkList &Lb, LinkList &Lc);     

/******线性表的静态单链表存储结构*****/
#define MAXSIZE 1000                                            //链表的最大长度
typedef struct{
    ElemType data;
    int cur;
}component, SLinkList[MAXSIZE];

//在静态单链线性表L中查找第一个值为e的元素
int LocateElem_SL(SLinkList S, ElemType e);                 
//将整个数组空间初始化成一个链表
void InitSpace_SL(SLinkList &space);                        
//从备用空间取得一个结点
int Malloc_SL(SLinkList &space);                            
//将空闲结点链结到备用链表上
void Free_SL(SLinkList &space, int k);                      


/**********线性表的双向链表存储结构**********/
typedef struct DuLNode{
    ElemType data;
    struct DuLNode *prior;
    struct DuLNode *next;
}DuLNode, *DuLinkList;
//在带头结点的双链循环线性表L中第i个位置之前插入元素e
Status LinstInsert_Dul(DuLinkList &L, int i, ElemType e);   
//在双链循环线性表L中,返回第i个元素的指针位置p
DuLinkList GetElemP_Dul(DuLinkList &L, int i);              
//删除带头结点的双链循环线性表L的第i个元素,i的合法值为1<<i<<表长
Status ListDelete_Dul(DuLinkList &L, int i, ElemType &e);   

#endif MYLIST_H_

MyList.c

#include "MyList.h"

void SqListTest(){
    SqList list1;
    int ret;
    int j = 1;
    ret = InitList_Sq(&list1);
    if(ret < 0){
        cout <<"SqListTest: init err" << endl;;
    }
    /*顺序线性表赋值*/
    for(int i = 0; i < 50; i++){
        list1.elem[i] = j;
        j += 2;
        list1.length++;         
    }
    /*判断顺序线性表是否为空*/
    ret=isEmpty(&list1);
    if(0 == ret){
        cout << "SqListTest: list is empty" << endl;
    }
    /*全部打印输出*/
    for(int i = 0; i < 50; i++){
        cout << list1.elem[i] << " ";
    }
    int index = LocateElem_Sq(&list1,3);
    cout << endl;
    cout << "LocateElem is " << index << endl;
    cout << "The length of SqList is " << list1.length << endl;
    cout << "Test is over!" << endl;
}

Status isEmpty(SqList *L)
{
    if(L->length==0)
        return 0;
    else
        return -1;
}

Status InitList_Sq(SqList *L){
    //构造一个空的线性表L
    L->elem = (ElemType *)malloc(SQ_LIST_INIT_SIZE * sizeof(ElemType));
    if(!L->elem){
        cout << "InitList_Sq: malloc err" << endl;//存储分配失败      
        exit(OVERFLOW);                 //空表长度为0
    L->listSize = SQ_LIST_INIT_SIZE;    //初始存储容量
    return OK;
}//InitList_Sq

Status ListInsert_Sq(SqList *L,int pos, ElemType insert_elem){
    //在顺序线性表L中第pos个位置之前插入新的元素insert_elem
    //i的合法值为0 <= pos <= ListLength_Sq(L)
    if(pos < 0 || pos > L->length){
        cout << "ListInsert_Sq: position is out of range" << endl;
        exit(ERROR);                            //pos值不合法
    }
    //当存储空间已满,增加分配
    if(L->length >= L->listSize){
        ElemType *newbase = (ElemType *)realloc(L->elem, (L->listSize + SQ_LISTINCREAMENT) * sizeof(ElemType));
        if(!newbase){
            cout << "ListInsert_Sq: realloc err" << endl;
            exit(OVERFLOW);
        }
        L->elem = newbase;
        L->listSize += SQ_LISTINCREAMENT;
    }
    ElemType *p, *q;
    p = L->elem + pos;                  //p为插入位置
    q = L->elem + L->length + 1;        //q为新线性表大小
    while(q != p){                      //将p之后的线性表存储向后移一位
        *q = *(q-1);
        q--;
    }
    *p = insert_elem;                   //插入insert_elem
    L->length += 1;                     //表增长1
    return OK;
}//ListInsert_Sq

Status ListDelete_Sq(SqList *L,int pos, ElemType &delete_elem){
    //在顺序线性表L中删除第pos个元素,并用delete_elem返回其值
    //pos的合法值为0 <= pos <= ListLength_Sq(L)
    if(pos < 0 || pos > L->length){
        cout << "ListDelete_Sq: position is out of range" << endl;
        exit(ERROR);                    //pos值不合法
    }
    ElemType *p;                
    p = L->elem + pos;                  //p为被删除元素的位置
    delete_elem = *p;                   //被删除元素的值赋给delete_elem
    while(p != L->elem + L->length){    //将p之后的线性表存储向前移一位
        *p = *(p + 1);
        p++;
    }
    L->length -= 1;
    return OK;
}//ListDelete_Sq

Status LocateElem_Sq(SqList *L, ElemType e){
    //在顺序线性表L中查找第1个值与e满足comare()的元素的位序列
    //若找到,则返回其在L中的位序,否则返回-1;
    int i = 0;      //i的初始值为第1个元素的位序
    ElemType *p;    
    p = L->elem;    //p的初始值为第1个元素的存储位置
    while(i <= L->length && *p != e){
        p++;
        ++i;
    }
    if(i <= L->length){
        return i;
    }
    else return INFEASIBLE;
}//LocateElem_Sq

void MergeList_Sq(SqList *La, SqList *Lb, SqList &Lc){
    //已知顺序线性表La和Lb的元素按值非递减排序
    //归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排序
    ElemType *pa = La->elem;
    ElemType *pb = Lb->elem;
    ElemType *pc;
    Lc.listSize = Lc.length = La->length + Lb->length;
    pc = Lc.elem = (ElemType *)malloc(Lc.listSize * sizeof(ElemType));
    if( !Lc.elem){
        cout << "MergeList_Sq: malloc err" << endl;         //存储分配失败
        exit(OVERFLOW);
    }
    ElemType *pa_last, *pb_last;
    pa_last = La->elem + La->length - 1;
    pb_last = Lb->elem + Lb->length - 1;
    while(pa <= pa_last && pb <= pb_last){          //归并
        if(*pa <= *pb){
            *pc++ = *pa++;
        }
        else{
            *pc++ = *pb++;
        }
    }
    while(pa <= pa_last){                       //插入La的剩余元素
        *pc++ = *pa++;
    }
    while(pb <= pb_last){                       //插入Lb的剩余元素
        *pc++ = *pb++;
    }
}//MergeList_Sq

Status GetElem_L(LinkList L, int i, ElemType &e){
    //L为带头结点的单链表的头指针。
    //当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR
    LinkList p = L->next;
    int j = 1;                      //初始化,p指向第一个结点,j为计数器
    while(p && j < i){              //顺指针向后查找,知道p指向第i个元素或p为空
        p = p->next;
        ++j;
    }
    if(!p || j > i){                //第i个元素不存在
        return ERROR;       
    }
    e = p->data;                    //取第i个元素
    return OK;
}//GetElem_L

Status ListInsert_L(LinkList &L, int i, ElemType e){
    //在带头结点的单链线性表L中第i个位置之前插入元素e
    LinkList p = L;
    int j = 0;
    while (p && j < i - 1)          //寻找第i-1个结点
    {
        p = p->next;
        ++j;
    }
    if(!p || j > i -1){             //i小于1或者大于表长+1
        return ERROR;
    }
    LinkList s = (LinkList)malloc(sizeof(LNode));       //生成新结点
    s->data = e; s->next = p->next;                     //插入L中
    p->next = s;
    return OK;
}//ListInsert_L

Status ListDelete_L(LinkList &L, int i, ElemType &e){
    //在带头结点的单链线性表L中,删除第i个元素,并由e返回其值
    LinkList p = L; int j = 0;
    while (p->next && j < i - 1)    //寻找第i个结点,并令p指向其前趋
    {
        p = p->next;
        ++j;
    }
    if(!(p->next) || j > i - 1){
        return ERROR;               //删除位置不合理
    }
    LinkList q = p->next;
    p->next = q->next;              //删除并释放结点
    e = q->data;
    free(q);
    return OK;
}//ListDelete_L

void CreateList_L(LinkList &L, int n){
    //逆位序输入n个元素的值,建立带头表结点的单链线性表L
    L = (LinkList)malloc(sizeof(LNode));
    L->next = NULL;                 //先建立一个带头结点的单链表
    for(int i = n; i > 0; --i){
        LinkList p = (LinkList)malloc(sizeof(LNode));
        cin >> p->data;
        p->next = L->next;          //插入元素值
        L->next = p;
    }
}//CreateList_L

void MergeList_L(LinkList &La, LinkList &Lb, LinkList &Lc){
    //已知单链线性表La和Lb的元素按值非递减排列。
    //归并La和Lb得到新的单链线性表Lc,Lc的元素也按非递减排列。
    LinkList pa = La->next;
    LinkList pb = Lb->next;
    LinkList pc;
    Lc = pc = La;                   //用La的头结点作为Lc的头结点
    while (pa && pb){
        if (pa->data <= pb->data){
            pc->next = pa;          //pa指向的结点连接到pc后
            pc = pa;                //pc = pc->next 使新结点变成工作结点
            pa = pa->next;          //继续比较La链表剩余的结点
        }
        else{
            pc->next = pb;
            pc = pb;
            pb = pb->next;
        }
    }
    pc->next = pa ? pa : pb;    //插入剩余段
    free(Lb);                   //释放Lb的头结点
}//MergeList_L

int LocateElem_SL(SLinkList S, ElemType e){
    //在静态单链线性表L中查找第一个值为e的元素
    //若找到,则返回它在L中的位序,否则返回0
    int i = S[0].cur;                   //i指示表中第一个结点
    while(i && S[i].data != e){         //在表中顺序链查找
        i = S[i].cur;
    }
    return i;
}//LocateElem_SL

void InitSpace_SL(SLinkList &space){
    //将一维数组space中各分量链成一个备用链表,space[0].cur为头指针,
    //“0”表示空指针
    for(int i = 0; i < MAXSIZE - 1; ++i){
        space[i].cur = i + 1;   
    }
    space[MAXSIZE - 1].cur = 0;
}//InitSpace_SL

int Malloc_SL(SLinkList &space){
    //若备用空间链表非空,则返回分配的结点下标,否则返回0
    int i = space[0].cur;
    if(space[0].cur){
        space[0].cur = space[i].cur;
    }
    return i;
}//Malloc_SL

void Free_SL(SLinkList &space, int k){
    //将下表为k的空闲结点回收到备用链表
    space[k].cur = space[0].cur;
    space[0].cur = k;
}//Free_SL

DuLinkList GetElemP_Dul(DuLinkList &L, int i){
    DuLinkList p = L->next;
    int j = 1;
    while (p && j < i){
        p = p->next;
        ++j;
    }
    if(!p || j > i){
        return ERROR;
    }
    return p;
}//GetElemP_Dul

Status LinstInsert_Dul(DuLinkList &L, int i, ElemType e){
    //在带头结点的双链循环线性表L中第i个位置之前插入元素e
    //i的合法值为1<<i<<表长+1
    DuLinkList p,s;
    if(!(p = GetElemP_Dul(L, i))){          //在L中确定插入位置指针p
        return ERROR;       //i等于表长加1时,p指向头结点;i大于表长加1时,
    }                                       //p = NULL
    if(!(s = (DuLinkList)malloc(sizeof(DuLNode)))){
        return ERROR;
    }
    s->data = e;
    s->prior = p->prior;
    p->prior->next = s;
    s->next = p;
    p->prior = s;
    return OK;
}//LinstInsert_Dul

Status ListDelete_Dul(DuLinkList &L, int i, ElemType &e){
    //删除带头结点的双链循环线性表L的第i个元素,i的合法值为1<<i<<表长
    DuLinkList p;
    if(!(p = GetElemP_Dul(L, i))){  //在L中确定第i个元素的位置指针p
        return ERROR;               //p = NULL,即第i个元素不存在
    }
    e = p->data;
    p->prior->next = p->next;
    p->next->prior = p->prior;
    free(p);
    return OK;
}//ListDelete_Dul


你可能感兴趣的:(数据结构,线性表)