第二章:线性表整理代码
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