线性表
顺序表
定义
#define LIST_INIT_SIZE 10
#define LISTINCREMENT 2
typedef struct
{
ElemType *elem;
int length;
int listsize;
}SqList;
也可以使用顺序表静态分配数组,其存储结构定义如下:
#define MAXSIZE 100
typedef struct
{
ElemType elem[MAXSIZE];
int last;/*记录线性表中最后一个元素在数组elem[ ]中的位置(下标值),空表置为-1*/
}SqList;
注意:静态数组或动态数组都可以实现顺序表。如果不加特殊说明,本书中采用的都是动态数组。
#include"public1.H"
#include"p2.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 DestroyList(SqList &L)
{
//销毁顺序线性表L
free(L.elem);
L.elem=NULL;
L.length=L.listsize=0;
return OK;
}
int LocateElem(SqList L, ElemType e)
{
//根据数据元素的值,返回它在线性表L中的位置
int i=1;
while ((i<=L.length)&&(*(L.elem+i-1)!=e))
i++;
if (i<=L.length)
return i;
else
return(0);
}
Status GetElem(SqList L,int i,ElemType &e)
{
//根据数据元素在线性表L中的位置,返回它的值
if(i<0||i>L.length)
return ERROR;
e=*(L.elem+i-1);
return OK;
}
Status ListInsert(SqList &L,int i,ElemType e)
{
// 在L中第i个位置之前插入新的数据元素e,L的长度加1
if(i>=L.listsize)
{
if(!(L.elem=(ElemType*)realloc(L.elem,sizeof(ElemType)*LISTINCREMENT)))
exit(OVERFLOW);
L.listsize+=LISTINCREMENT;
}
if(i<0)
return ERROR;
for(int j=L.length;j>=i;j--)
{
*(L.elem+j)=*(L.elem+j-1);
}
*(L.elem+i-1)=e;
L.length++;
return OK;
}
Status ListDelete(SqList &L,int i,ElemType &e)
{
//删除L的第i个数据元素,并用e返回其值,L的长度减1
if(i<0||i>L.length)
return ERROR;
e=*(L.elem+i-1);
for(int j=i;j<L.length;j++)
{
*(L.elem+j-1)=*(L.elem+j);
}
L.length--;
return OK;
}
Status PriorElem(SqList L,ElemType cur_e,ElemType &pre_e)
{
// 若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败
int location=LocateElem(L,cur_e);
if((!location)||cur_e==*(L.elem))
return ERROR;
pre_e=*(L.elem+location-2);
return OK;
}
Status visit(SqList L)
{
//按序输出顺序表的各个元素值
int i;
for(i=1;i<=L.length;i++)
printf("%d ",*(L.elem+i-1));
printf("L.elem=%u L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize);
return OK;
}
int main()
{
SqList L;
ElemType e,pre_elem;
Status i;
int j;
i=InitList(L);
visit(L);
for(j=1;j<=5;j++)
i=ListInsert(L,1,j);
printf("在L的表头依次插入1~5后:*L.elem=");
visit(L);
for(j=1;j<=5;j++)
*(L.elem+L.length+j-1)=j;
printf("在L的表尾依次插入1~5后:*L.elem=");
L.length=L.length+5;
visit(L);
ListInsert(L,1,0);
printf("在L的表头插入0后:*L.elem=");
visit(L);
i=LocateElem(L,1);
printf("值为1的数据元素在顺序表中的位置是");
printf("%d ",i);
printf("\n");
GetElem(L,5,e);
printf("第5个元素的值为:%d\n",e);
printf("在L中删除第三个数据元素:*L.elem=");
ListDelete(L,3,e);
visit(L);
printf("第五个元素的值为:%d",*(L.elem+4));
if(PriorElem(L,*(L.elem+4),pre_elem))
printf(",它的前驱为:%d\n",pre_elem);
else
printf(",你输入的是第一个数,它没有前驱!\n");
DestroyList(L);
printf("销毁L后:L.elem=%u L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize);
return 0;
}
单链表
单链表存储结构定义
typedef int ElemType;
typedef struct LNode
{
ElemType data;
LNode *next;
}LNode;
typedef LNode *LinkList;
函数部分:
#include"public1.H"
#include"p3.h"
Status InitList(LinkList &L)
{
// 构造一个空的单链表L
L=(LinkList)malloc(sizeof(LNode));
if (!L)
exit(OVERFLOW);
L->next=NULL;
return OK;
}
Status DestroyList(LinkList &L)
{
// 销毁单链表L
LinkList p;
while(p=L->next)
{
L->next=p->next;
free(p);
}
return OK;
}
void CreateList(LinkList &L,int n)
{
// 逆位序输入n个元素的值,建立带表头结构的单链线性表L
int i;
LinkList p;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
printf("请输入%d个数据:",n);
for(i=n;i>0;--i)
{
p=(LinkList)malloc(sizeof(LNode));
scanf("%d",&p->data);
p->next=L->next;
L->next=p;
}
}
void CreateList2(LinkList &L,int n)
{
// 正位序输入n个元素的值,建立带表头结构的单链线性表
int i;
LinkList p,tail;
tail=L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
printf("请输入%d个数据:", n);
for(i=0;i<n;i++)
{
p=(LinkList)malloc(sizeof(LNode));
scanf("%d", &p->data);
p->next=NULL;
tail->next=p;
tail=p;
}
}
int ListLength(LinkList L)
{
// 返回L中数据元素个数
int num=0;
LinkList p=L->next;
while(p)
{
num++;
p=p->next;
}
return num;
}
Status GetElem(LinkList L,int i,ElemType &e)
{
// L为带头结点的单链表的头指针。当第i个元素存在时,其值赋给e并返回OK,否则返回 ERROR
int j=1;
LinkList p=L->next;
while(p&&j<i)
{
p=p->next;
j++;
}
if(!p||j>i)
return ERROR;
e=p->data;
return OK;
}
int LocateElem(LinkList L,ElemType e)
{
// 返回L中第1个值为e 的数据元素的位序,若这样的数据元素不存在,则返回值为0
LinkList p=L->next;
int num=0;
while(p)
{
num++;
if(p->data==e)
return num;
else
p=p->next;
}
return 0;
}
Status visit(LinkList L)
{
//按序输出单链表的各个元素值
LinkList p=L->next;
while(p)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
return OK;
}
Status ReverseVisit(LinkList L)
{
//逆位序输出单链表的各个元素的值
LinkList p=L->next,tail;
int length=ListLength(L);
while(length)
{
int num=0;
p=L->next; //两行代码应该放在循环内部,进行初始化
while(p&&num!=length)
{
//找到尾结点
num++;
tail=p;
p=p->next;
}
printf("%d ",tail->data);
length--;
}
return OK;
}
Status ListInsert(LinkList &L,int i,ElemType e)
{
//在带头节点的单链表L中第i个位置之前插入元素e
if(i<0) return ERROR;
int count=1;
LinkList p=L->next,pre=L,q;
for( ;p&&count!=i;count++,p=(pre=p)->next);//找到第i个位置及其pre的指针
if(count>i) return ERROR; //没有找到第i个位置
q=(LinkList)malloc(sizeof(LNode)); //创建一个新的结点存放元素e
if(!q) exit(OVERFLOW);
q->data=e;
pre->next=q;
q->next=p;
return OK;
}
Status ListDelete(LinkList &L,int i,ElemType& e)
{
//在带头节点的单链表L中,删除第i个元素,并由e返回其值
if(i<0) return ERROR;
int count=1;
LinkList pre=L,p=L->next;
for( ;p&&count!=i;count++,p=(pre=p)->next);
//find i_th node and its previous node
if(count>i) return ERROR;
e=p->data;
pre->next=p->next;
free(p);
return OK;
}
void MergeList(LinkList &La, LinkList &Lb, LinkList &Lc)
{
//已知线性表La和Lb中的数据元素按值非递减排列
//归并La和Lb得到新的线性表Lc,Lc的数据元素也按值非递减排列
Lc=(LinkList)malloc(sizeof(LNode));
LinkList pa=La->next,pb=Lb->next,pc=Lc;
while(pa&&pb)
{
//到La,Lb两个表其中一个结束为止,将元素按非递减插入链表Lc中
if(pa->data<pb->data)
pa=(pc=pc->next=pa)->next;
else if(pa->data>pb->data)
pb=(pc=pc->next=pb)->next;
else
{
pc=pc->next=pa;
pa=pa->next;
pc=pc->next=pb;
pb=pb->next;
}
}
while(pa&&!pb) //Lb表结束
pa=(pc=pc->next=pa)->next;
while(pb&&!pa) //La表结束
pb=(pc=pc->next=pb)->next;
pc->next=NULL; //将Lc表尾部置空
}
//实现归并算法MergeList2,使重复的元素只保存一次
void MergeList2(LinkList &La,LinkList &Lb,LinkList &Lc)
{
//已知线性表La和Lb中的数据元素按值递减排列
//归并La和Lb得到新的线性表Lc,Lc的数据元素也按值递减排列
Lc=(LinkList)malloc(sizeof(LNode));
LinkList pa=La->next,pb=Lb->next,pc=Lc;
while(pa&&pb)
{
//到La,Lb两个表其中一个结束为止,将元素按递减插入链表Lc中
if(pa->data<pb->data)
pa=(pc=pc->next=pa)->next;
else if(pa->data>pb->data)
pb=(pc=pc->next=pb)->next;
else
{
pc=pc->next=pa;
pa=pa->next;
pb=pb->next;
}
}
while(pa&&!pb) //Lb表结束
pa=(pc=pc->next=pa)->next;
while(pb&&!pa) //La表结束
pb=(pc=pc->next=pb)->next;
pc->next=NULL; //将Lc表尾部置空
}
栈
void CreateList_L(LinkList &L, int n){
//逆位序输入n个元素的值,建立带表头结点的单链表L。
int i;
LinkList p;
L=(LinkList) malloc (sizeof(LNode));
L->next=NULL; //建一个带头结点的单链表
printf("Input %d integers: ",n);
for (i=n; i>0 ; --i )
{
p= (LinkList) malloc (sizeof(LNode)); //生成新结点
scanf("%d",&p->data); //输入元素值
p->next=L->next; L->next =p; //插入到表头
}
}// CreateList_L
void PrintList_L(LinkList L)
{
//递归地将链表输出
printf("%d ",L->data);
if(L->next) //当下一结点为空的时候,结束递归
PrintList_L(L->next);
}
LinkList reverse(LinkList p)
{
//递归地将单链表逆置,返回值为链表开始结点
LinkList L,q;
if(!p->next) return p; //结束递归条件,返回值为链表头结点
L=reverse(p->next);
p->next->next=p;
p->next=NULL;
return L;//返回头节点
}
int ListLength(LinkList L)
{
//递归地求链表长度,返回值为链表长度
if(!L->next) return 1;
return (ListLength(L->next)+1);
}
void ReversePrintList(LinkList L)
{
//递归地逆序输出链表
if(L->next)
ReversePrintList(L->next);
printf("%d ",L->data);
}
LinkList MergeList(LinkList La,LinkList Lb)
{
//递归地将两个有序链表合并,返回值为头结点
LinkList L,p;
if(!La) //当链表La结束时
return Lb;
if(!Lb) //当链表Lb结束时
return La;