您的位置:首页 > 理论基础 > 数据结构算法

学习笔记------数据结构(C语言版) 扩展的线性单链表及归并

2016-01-15 09:23 513 查看
//Function realization.cpp

#include"predefined.h"
#include"ExtenLinkedList.h"
Status MakeNode_E(Link *p,ElemType e)
//分配由p指向的值为e的结点,并返回OK;
//若分配失败,则返回ERROE。
{
	(*p)=(Link)malloc(sizeof(LNode));
	if(!(*p)) exit(OVERFLOW);
	(**p).data=e;
	(**p).next=NULL;
	return OK;
}

void FreeNode_E(Link *p)
//释放p所指的结点。
{
	free(*p);
	*p=NULL;
}

Status InitList_E(LinkList *L)
//构造一个空的线性链表L。
{
	Link p;
	p=(Link)malloc(sizeof(LNode));
	if(!p) exit(OVERFLOW);
	(*p).next=NULL;
	(*p).data=0;
	(*L).head=(*L).tail=p;
	(*L).len=0;
	return OK;
}

Status DestroyList_E(LinkList *L)
//销毁线性链表L,L不再存在。
{
	Link p,q;  
	p=(*L).head;  
    while(p)  
    {  
        q=p;
  		p=(*p).next;
		free(q); 
    }
	(*L).head=(*L).tail=NULL;
	(*L).len=0;
    return OK;
}

Status ClearList_E(LinkList *L)
//将线性链表L重置为空表,并释放原链表的结点空间。
{
	Link p,q;
	p=(*(*L).head).next;
	while(p)
	{
		q=p;
		p=(*p).next;
		free(q);
	}
	(*(*L).head).next=NULL;
	(*L).len=0;
	(*L).tail=(*L).head;
	return OK;
}

Status InsFirst_E(LinkList *L,Link h,Link s)
//已知h指向线性链表的头结点,将s所指结点插入在第一个结点之前。
{
	(*s).next=(*h).next;
	(*h).next=s;
	(*L).len++;
	if((*L).tail==h) (*L).tail=s;
	return OK;
}

Status DelFirst_E(LinkList *L,Link h,Link *q)
//已知h指向线性链表的头结点,删除链表中的第一个结点并以q返回。
{
	if(!((*h).next)) return ERROR;
	if(!(*(*h).next).next) (*L).tail=(*L).head;
	*q=(*h).next;
	(*h).next=(*(*h).next).next;
	(*L).len--;
	return OK;
}

Status Append_E(LinkList *L,Link s)
//将指针s所指(彼此以指针相连)的一串结点链接在线性表L的最后一个结点
//之后,并改变链表L的尾指针指向新的尾结点。
{
	Link p,q;
	int count=0;
	p=(*L).tail;
	(*p).next=s;
	while(s)
	{
		q=s;
		s=(*s).next;
		count++;
	}
	(*L).tail=q;
	(*L).len+=count;
	return OK;
}

Status Remove_E(LinkList *L,Link *q)
//删除线性链表L中的尾结点并以q返回,改变链表L的尾指针指向新的尾结点。
{
	Link p,r;
	p=(*L).head;
	if(p)
	{
		while((*p).next)
		{
			r=p;
			p=(*p).next;
		}
		(*r).next=NULL;
		*q=p;
		(*L).tail=r;
		(*L).len--;
		return OK;
	}
	*q=NULL;
	return FALSE;
}

Status InsBefore_E(LinkList *L,Link *p,Link s)
//已知p指向线性链表L中的一个结点,将s所指结点插入在p所指结点之前,
//并修改指针p指向新插入的结点。
{
	if(!(*p)||(*L).head==*p||!(*L).head) return ERROR;
	Link q,r;
	q=(*L).head;
	while(!(q==*p))
	{
		r=q;
		q=(*q).next;
		if(!q) return ERROR;
	}
	(*s).next=*p;
	(*r).next=s;
	*p=s;
	(*L).len++;
	return OK;
}

Status InsAfter_E(LinkList *L,Link *p,Link s)
//已知p指向线性链表L中的一个结点,将s所指结点插入在p所指结点之后,
//并修改指针p指向新插入的结点。
{
	if(!(*p)||!(*L).head) return ERROR;
	Link q;
	(*s).next=(**p).next;
	(**p).next=s;
	if(!(**p).next) (*L).tail=s;
	*p==s;
	(*L).len++;
	return OK;
}

Status SetCurElem_E(Link *p,ElemType e)
//已知p指向线性链表中的一个结点,用e更新p所指结点中数据元素的值。
{
	if(!(*p)) return ERROR;
	(**p).data=e;
	return OK;
}

ElemType GetCurElem_E(Link p)
//已知p指向线性链表中的一个结点,返回p所指结点中数据元素的值。
{ 
	if(!p) return ERROR;
	return (*p).data;
}

Status ListEmpty_E(LinkList L)
//若线性表L为空表,则返回TRUE,否则返回FALSE。
{
	if(L.len==0) return TRUE;
	else return FALSE;
}

int ListLength_E(LinkList L)
//返回线性链表L中元素的个数。
{
	return L.len;
}

Position GetHead_E(LinkList L)
//返回线性链表L中头结点的位置。
{
	return L.head;
}

Position GetLast_E(LinkList L)
//返回线性链表L中最后一个结点的位置。
{
	return L.tail;
}

Position PriorPos_E(LinkList L,Link p)
//已知p指向线性链表L中的一个结点,返回p所指结点的直接前驱的位置,
//若无前驱,则返回NULL。
{
	if((L.head==p)||(*L.head).next==p) return NULL;
	Link q,r;
	q=L.head;
	while(!(q==p))
	{
		r=q;
		q=(*q).next;
		if(!q) return NULL;
	}
	return r;
}

Position NextPos_E(LinkList L,Link p)
//已知p指向线性链表L中的一个结点,返回p所指结点的直接后继的位置,
//若无后继,则返回NULL。
{
	return (*p).next;
}

Status LocatePos_E(LinkList L,int i,Link *p)
//返回p指示线性链表L中第i个结点的位置并返回OK,i值不合法时返回ERROR。
{
	*p=L.head;
	if(i<0||i>L.len) return ERROR;
	while(*p&&i>0)
	{
		(*p)=(**p).next;
		i--;
	}
	return OK;
}

Position LocateElem_E(LinkList L,ElemType e,Status(*compare)(ElemType,ElemType))
//返回链表L中第1个与e满足函数compare()判定关系的元素的位置,
//若不存在这样的元素,则返回NULL。
{
	Link p;
	p=(*(L).head).next;
	while(p&&!compare((*p).data,e))
		p=(*p).next;
	return p;
}

Status ListTraverse_E(LinkList L,Status(*visit)(ElemType))
//依次对L中每个元素调用函数visit()。一旦visit()失败,则操作失败。
{
	Link p;
	int i;
	p=(*(L).head).next;
	for(i=0;i<L.len;i++)
	{
		visit((*p).data);
		p=(*p).next;
	}
	return OK;
}

Status ListInsert_L_E(LinkList *L,int i,ElemType e)
//算法2.20:在带头结点的单链线性表L的第i个元素之前插入元素e
{
	Link h,s;
	if(!LocatePos_E(*L,i-1,&h)) return ERROR;
	if(!MakeNode_E(&s,e)) return ERROR;
	InsFirst_E(L,h,s);
	return OK;
}

Status MergList_L_E(LinkList *La,LinkList *Lb,LinkList *Lc,int (*compare)(ElemType,ElemType))
//算法2.21:已知单链线性表La和Lb的元素按值非递减排列。
//归并La和La得到新的单链线性表Lc,Lc的元素也按值非递减排列。
{
	Position ha,hb,pa,pb;
	ElemType a,b;
	Link q;
	if(!InitList_E(Lc)) return ERROR;
	ha=GetHead_E(*La);
	hb=GetHead_E(*Lb);
	pa=NextPos_E(*La,ha);
	pb=NextPos_E(*Lb,hb);
	while(pa&&pb)
	{
		a=GetCurElem_E(pa);
		b=GetCurElem_E(pb);
		if(compare(a,b)<=0)
		{
			DelFirst_E(La,ha,&q);
			InsFirst_E(Lc,(*Lc).tail,q);
			pa=NextPos_E(*La,ha);
		}
		else
		{
			DelFirst_E(Lb,hb,&q);
			InsFirst_E(Lc,(*Lc).tail,q);
			pb=NextPos_E(*Lb,hb);
		}
	}
	if(pa) Append_E(Lc,pa);
	else Append_E(Lc,pb);
	FreeNode_E(&ha);
	FreeNode_E(&hb);
	return OK;
}


//main.cpp
#include"predefined.h"
#include"ExtenLinkedList.h"
Status visit(ElemType e)
{
	printf("%d ",e);
	return OK;
}

Status CmpGreater(ElemType m,ElemType n)
{
	if(m>n) return TRUE;
	else return FALSE;
}

int main()
{
	LinkList La,Lb,Lc;
	Status s;
	int n,m,i;
	Link p,q,ss;
	ElemType e;
	printf("Function 1\n★函数InitList_E(LinkList *L)测试...\n");
	s=InitList_E(&La);
	printf("▲初始化扩展的单链表La: %d (0:失败 1:成功)\n\n",s);
	printf("Function 2\n★函数ListEmpty_E(LinkList L)测试...\n");
	s=ListEmpty_E(La);
	printf("▲表La是否为空表: %d   (0:否 1:是)\n\n",s);
	printf("Function 3\n★函数ListInsert_L_E(LinkList *L,int i,ElemType e)测试...\n");
	printf("▲请输入准备向La输入的个数:");  
    scanf("%d",&n);  
    for(i=1;i<=n;i++)  
    {  
        printf("▲请输入La第%d个数:",i);  
        scanf("%d",&m);  
        s=ListInsert_L_E(&La,i,m);
        printf("▲插入成功?:%d   (1:成功 0:失败)\n",s);  
    }  
    printf("\n");
	printf("Function 4\n★函数ListTraverse_E(LinkList L,Status(*visit)(ElemType))测试...\n");
	printf("▲La中的元素为:La={");  
    ListTraverse_E(La,visit);
    printf("}\n\n"); 
	printf("Function 5\n★函数ListLength_E(LinkList L)测试...\n");
	s=ListLength_E(La);
	printf("▲La的长度为:%d\n\n",s);
	printf("Function 6\n★函数LocatePos_E(LinkList L,int i,Link *p)测试...\n");
	LocatePos_E(La,3,&p);
	printf("▲表La第3个元素\"%d\"的地址为:0x%x\n\n",(*p).data,p);
	printf("Function 7\n★函数PriorPos_E(LinkList L,Link p)测试...\n");
	q=PriorPos_E(La,p);
	printf("▲指针p指向的元素\"%d\"的前驱元素为\"%d\"\n\n",(*p).data,(*q).data);
	printf("Function 8\n★函数NextPos_E(LinkList L,Link p)测试...\n");
	q=NextPos_E(La,p);
	printf("▲指针p指向的元素\"%d\"的后继元素为\"%d\"\n\n",(*p).data,(*q).data);
	printf("Function 9\n★函数LocateElem_E(LinkList L,ElemType e,Status(*compare)(ElemType,ElemType))测试...\n");
	p=LocateElem_E(La,3,CmpGreater);
	printf("▲表La中第一个大于3的元素\"%d\"的地址为:0x%x\n\n",(*p).data,p);
	printf("Function 10\n★函数MakeNode_E(Link *p,ElemType e)测试...\n");
	printf("▲创建结点p...\n");
	MakeNode_E(&p,111);
	printf("▲创建结点q...\n\n");
	MakeNode_E(&q,222);
	printf("Function 11\n★函数GetCurElem_E(Link p)测试...\n");
	e=GetCurElem_E(p);
	printf("▲结点p的值:%d\n",e);
	e=GetCurElem_E(q);
	printf("▲结点q的值:%d\n\n",e);
	printf("Function 12\n★函数SetCurElem_E(Link *p,ElemType e)测试...\n");
	printf("▲用666替换p结点中的值...\n");
	SetCurElem_E(&p,666);
	e=GetCurElem_E(p);
	printf("▲结点p的值:%d\n\n",e);
	printf("Function 13\n★函数FreeNode_E(Link *p)测试...\n");
	printf("▲销毁p结点前:");
	p?printf("p存  在!!!\n"):printf("p不存在!!!\n");
	FreeNode_E(&p);
	printf("▲销毁p结点后:");
	p?printf("p存  在!!!\n\n"):printf("p不存在!!!\n\n");
	printf("Function 14\n★函数Append_E(LinkList *L,Link s)测试...\n");
	printf("▲将q结点插在La最后一个结点之后...\n");
	Append_E(&La,q);
	printf("▲La中的元素为:La={");  
    ListTraverse_E(La,visit);
    printf("}\n\n");
	printf("Function 15\n★函数Remove_E(LinkList *L,Link *q)测试...\n");
	printf("▲删除L中最后一个结点,用p接受最后一个结点...\n");
	Remove_E(&La,&p);
	printf("▲La中的元素为:La={");  
    ListTraverse_E(La,visit);
    printf("}\n\n");
	printf("Function 16\n★函数InsFirst_E(LinkList *L,Link h,Link s)测试...\n");
	printf("▲创建值为888的结点p...\n");
	MakeNode_E(&p,888);
	printf("▲令q指向La中第3个元素...\n");
	LocatePos_E(La,3,&q);
	printf("▲将p结点插入到以q作为头结点的链表第一个结点之前...\n");
	InsFirst_E(&La,q,p);
	printf("▲La中的元素为:La={");  
    ListTraverse_E(La,visit);
    printf("}\n\n");
	printf("Function 17\n★函数DelFirst_E(LinkList *L,Link h,Link *q)测试...\n");
	printf("▲删除La中以第3个结点q为头结点的链表的第一个结点...\n");
	DelFirst_E(&La,q,&p);
	printf("▲La中的元素为:La={");  
    ListTraverse_E(La,visit);
    printf("}\n\n");
	printf("Function 18\n★函数GetHead_E(LinkList L)测试...\n");
	p=GetHead_E(La);
	printf("▲La的头指针p=La.head=0x%x\n\n",p);
    printf("Function 19\n★函数GetLast_E(LinkList L)测试...\n");
	q=GetLast_E(La);
	printf("▲La的尾指针q=La.tail=0x%x\n\n",q);
	printf("Function 20\n★函数InsBefore_E(LinkList *L,Link *p,Link s)测试...\n");
	printf("▲创建值为999的结点ss...\n");
	MakeNode_E(&ss,999);
	printf("▲将结点ss插入到尾结点q之前...\n");
	InsBefore_E(&La,&q,ss);
	printf("▲La中的元素为:La={");  
    ListTraverse_E(La,visit);
    printf("}\n\n");
	printf("Function 21\n★函数InsAfter_E(LinkList *L,Link *p,Link s)测试...\n");
	printf("▲创建值为777的结点ss...\n");
	MakeNode_E(&ss,777);
	printf("▲将结点ss插入到头结点p之后...\n");
	InsAfter_E(&La,&p,ss);
	printf("▲La中的元素为:La={");  
    ListTraverse_E(La,visit);
    printf("}\n\n");
	printf("Function 22\n★函数ClearList_E(LinkList *L)测试...\n");
	printf("▲置空前:");
	ListEmpty_E(La)?printf("La为空!!!\n"):printf("La非空!!!\n");
	ClearList_E(&La);
	printf("▲置空后:");
	ListEmpty_E(La)?printf("La为空!!!\n\n"):printf("La非空!!!\n\n");
	printf("Function 22\n★函数DestroyList_E(LinkList *L)测试...\n");
	printf("▲销毁前:");
	(La.head!=NULL&&La.tail!=NULL)?printf("La存  在!!!\n"):printf("La不存在!!!\n");
	DestroyList_E(&La);
	printf("▲销毁后:");
	(La.head!=NULL&&La.tail!=NULL)?printf("La存  在!!!\n\n"):printf("La不存在!!!\n\n");
	printf("Function 23\n★函数MergList_L_E(LinkList *La,LinkList *Lb,LinkList *Lc,int (*compare)(ElemType,ElemType))测试...\n");
	s=InitList_E(&La);
	printf("▲初始化扩展的单链表La: %d (0:失败 1:成功)\n\n",s);
	s=InitList_E(&Lb);
	printf("▲初始化扩展的单链表Lb: %d (0:失败 1:成功)\n\n",s);
	printf("▲请输入准备向La输入的个数:");  
    scanf("%d",&n);  
    for(i=1;i<=n;i++)  
    {  
        printf("▲请输入La第%d个数:",i);  
        scanf("%d",&m);  
        s=ListInsert_L_E(&La,i,m);
        printf("▲插入成功?:%d   (1:成功 0:失败)\n",s);  
    }  
    printf("\n");
	printf("▲La中的元素为:La={");  
    ListTraverse_E(La,visit);
    printf("}\n\n");//
	printf("▲请输入准备向Lb输入的个数:");  
    scanf("%d",&n);  
    for(i=1;i<=n;i++)  
    {  
        printf("▲请输入Lb第%d个数:",i);  
        scanf("%d",&m);  
        s=ListInsert_L_E(&Lb,i,m);
        printf("▲插入成功?:%d   (1:成功 0:失败)\n",s);  
    }  
    printf("\n");
	printf("▲Lb中的元素为:Lb={");  
    ListTraverse_E(Lb,visit);
    printf("}\n\n");
	MergList_L_E(&La,&Lb,&Lc,CmpGreater);
	printf("▲Lc中的元素为:Lc={");  
    ListTraverse_E(Lc,visit);
    printf("}\n\n");
}


//ExtenLinkedList.h

typedef struct LNode//结点类型
{
	ElemType data;
	struct LNode *next;
}LNode,*Link,*Position;
typedef struct//链表类型
{
	Link head,tail;
	int len;
}LinkList;
Status MakeNode_E(Link *p,ElemType e);
void FreeNode_E(Link *p);
Status InitList_E(LinkList *L);
Status DestroyList_E(LinkList *L);
Status ClearList_E(LinkList *L);
Status InsFirst_E(LinkList *L,Link h,Link s);
Status DelFirst_E(LinkList *L,Link h,Link *q);
Status Append_E(LinkList *L,Link s);
Status Remove_E(LinkList *L,Link *q);
Status InsBefore_E(LinkList *L,Link *p,Link s);
Status InsAfter_E(LinkList *L,Link *p,Link s);
Status SetCurElem_E(Link *p,ElemType e);
ElemType GetCurElem_E(Link p);
Status ListEmpty_E(LinkList L);
int ListLength_E(LinkList L);
Position GetHead_E(LinkList L);
Position GetLast_E(LinkList L);
Position PriorPos_E(LinkList L,Link p);
Position NextPos_E(LinkList L,Link p);
Status LocatePos_E(LinkList L,int i,Link *p);
Position LocateElem_E(LinkList L,ElemType e,Status(*compare)(ElemType,ElemType));
Status ListTraverse_E(LinkList L,Status(*visit)(ElemType));
Status ListInsert_L_E(LinkList *L,int i,ElemType e);
Status MergList_L_E(LinkList *La,LinkList *Lb,LinkList *Lc,int (*compare)(ElemType,ElemType));

Status visit(ElemType e);
Status CmpGreater(ElemType m,ElemType n);


//predefined.h

#include "stdio.h"
#include "stdlib.h"
#define   TRUE           1
#define   FALSE          0
#define   OK             1
#define   ERROR          0
#define   INFEASIBLE    -1
#define   OVERFLOW      -2
typedef   int Status;
typedef   int ElemType;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: