双链表的元素排序,双链表的的所有基本算法(初始化,创建,插入,删除,查找等)(李春葆版)

双链表基本运算实现
本文详细介绍了一种双链表的数据结构实现,包括初始化、销毁、判断是否为空、获取长度、输出、查找元素、插入元素、删除元素等基本操作,并通过实例演示了这些操作的具体流程。
//文件名:algo2-3.cpp
#include <stdio.h>
#include <malloc.h>
typedef char ElemType;
typedef struct DNode		//定义双链表结点类型
{
	ElemType data;
	struct DNode *prior;	//指向前驱结点
	struct DNode *next;	
	ElemType freq;	//指向后继结点
} DLinkList;
void InitList(DLinkList *&L)	//初始化
{
	L=(DLinkList *)malloc(sizeof(DLinkList));  	//创建头结点
	L->prior=L->next=NULL;
}
void DestroyList(DLinkList *&L)	//销毁线性表
{
	DLinkList *p=L,*q=p->next;
	while (q!=NULL)
	{
		free(p);
		p=q;
		q=p->next;
	}
	free(p);
}
bool ListEmpty(DLinkList *L)	//判线性表是否为空表
{
	return(L->next==NULL);
}
int ListLength(DLinkList *L)	//求线性表的长度
{
	DLinkList *p=L;int i=0;
	while (p->next!=NULL)
	{
		i++;
		p=p->next;
	}
	return(i);
}
void DispList(DLinkList *L)	//输出线性表
{
	DLinkList *p=L->next;
	while (p!=NULL)
	{
		printf("%c ",p->data);
		p=p->next;
	}
	printf("\n");
}
bool GetElem(DLinkList *L,int i,ElemType &e)	//求线性表中某个数据元素值
{
	int j=0;
	DLinkList *p=L;
	while (j<i && p!=NULL)
	{
		j++;
		p=p->next;
	}
	if (p==NULL)
		return false;
	else
	{
		e=p->data;
		return true;
	}
}
int LocateElem(DLinkList *L,ElemType e)	//按元素值查找
{
	int n=1;
	DLinkList *p=L->next;
	while (p!=NULL && p->data!=e)
	{
		n++;
		p=p->next;
	}
	if (p==NULL)
		return(0);
	else
		return(n);
}
bool ListInsert(DLinkList *&L,int i,ElemType e)	//插入数据元素
{
	int j=0;
	DLinkList *p=L,*s;
	while (j<i-1 && p!=NULL)
	{
		j++;
		p=p->next;
	}
	if (p==NULL)	//未找到第i-1个结点
		return false;
	else			//找到第i-1个结点*p
	{
		s=(DLinkList *)malloc(sizeof(DLinkList));	//创建新结点*s
		s->data=e;	
		s->next=p->next;		//将*s插入到*p之后
		if (p->next!=NULL) p->next->prior=s;
		s->prior=p;
		p->next=s;
		return true;
	}
}
bool ListDelete(DLinkList *&L,int i,ElemType &e)	//删除数据元素
{
	int j=0;
	DLinkList *p=L,*q;
	while (j<i-1 && p!=NULL)
	{
		j++;
		p=p->next;
	}
	if (p==NULL)				//未找到第i-1个结点
		return false;
	else						//找到第i-1个结点*p
	{
		q=p->next;				//q指向要删除的结点
		if (q==NULL) return false;	//不存在第i个结点
		e=q->data;
		p->next=q->next;		//从单链表中删除*q结点
		if (p->next!=NULL) p->next->prior=p;
		free(q);				//释放*q结点
		return true;
	}
}
void Sort(DLinkList *&head)	//双链表元素排序
{
	DLinkList *p=head->next,*q,*r;
	if (p!=NULL)			//若原双链表中有一个或以上的数据结点
	{
		r=p->next;			//r保存*p结点后继结点的指针
		p->next=NULL;		//构造只含一个数据结点的有序表
		p=r;
		while (p!=NULL)
		{
			r=p->next;		//r保存*p结点后继结点的指针
			q=head;
			while (q->next!=NULL && q->next->data<p->data)	//在有序表中找插入*p的前驱结点*q
				q=q->next;
			p->next=q->next;				//将*p插入到*q之后
			if (q->next!=NULL) q->next->prior=p;
			q->next=p;
			p->prior=q;
			p=r;
		}
	}
}
//验证实验内容2
int LocateNode(DLinkList *L,ElemType e)
{  
	DLinkList *p=L->next,*pre;  //p指向头结点 
	DLinkList *q,*s;       //定义节点q,s 
	while (p!=NULL && p->data!=e)//用while找出数据是e的节点 
	p=p->next;
	if (p==NULL)          //如果没有找到返回0 
 	return(0);
	else					//找到了数据是e的节点	
	{	p->freq++;			//频率加一 
  		if(p->freq<p->prior->freq) 
		  	return(1);
 		q=p->prior;			// 如果p的频率小于p前面的频率 
 		q->next=p->next;
		p->next->prior=q;	//交换p与p->prior的位置 
		s=p;
		while(p->prior!=L&&p->prior->freq<s->freq) //用while一直把p->freq和p->prior->freq作比较 
		p=p->prior;								//如果前面的freq小于p的ferq则指针向前指直到前面的freq大于p的ferq跳出循环 
		if(p->prior==L)
		{
			s->next=L->next;
			L->next->prior=s;
			L->next=s;
			s->prior=L;
		}
		else                       
		{s->next=p;
		p->next->prior=s;
		s->prior=p->prior;
		p->prior->next=s;
          }
return(1);}
}

//文件名:exp2-3.cpp
#include <stdio.h>
#include <malloc.h>
#include "algo2-3.cpp" 
typedef char ElemType;
extern void InitList(DLinkList *&L);		//以下均为外部函数
extern void DestroyList(DLinkList *&L);
extern bool ListEmpty(DLinkList *L);
extern int ListLength(DLinkList *L);
extern void DispList(DLinkList *L);
extern bool GetElem(DLinkList *L,int i,ElemType &e);
extern int LocateElem(DLinkList *L,ElemType e);
extern bool ListInsert(DLinkList *&L,int i,ElemType e);
extern bool ListDelete(DLinkList *&L,int i,ElemType &e);
int main()
{
	DLinkList *h;
	
	ElemType e;
	
	printf("双链表的基本运算如下:\n");
	printf("  (1)初始化双链表h\n");
	InitList(h);
	printf("  (2)依次采用尾插法插入a,b,c,d,e元素\n");
	ListInsert(h,1,'a');
	ListInsert(h,2,'b');
	ListInsert(h,3,'c');
	ListInsert(h,4,'d');
	ListInsert(h,5,'e');
	printf("  (3)输出双链表h:");
	DispList(h);
	printf("  (4)双链表h长度=%d\n",ListLength(h));
	printf("  (5)双链表h为%s\n",(ListEmpty(h)?"空":"非空"));
	GetElem(h,3,e);
	printf("  (6)双链表h的第3个元素=%c\n",e);
	printf("  (7)元素a的位置=%d\n",LocateElem(h,'a'));
	printf("  (8)在第4个元素位置上插入f元素\n");
	ListInsert(h,4,'f');
	printf("  (9)输出双链表h:");
	DispList(h);
	printf("  (10)删除h的第3个元素\n");
	//ListDelete(h,3,e);
	printf("  (11)输出双链表h:");
	DispList(h);
	printf("(12)验证试验二locate元素'f'':");		 
	char c='f';
	LocateNode(h,c);
		DispList(h);
	printf("  (13)释放双链表h\n");
	DestroyList(h);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值