双向循环链表基本操作(初始化,插入,删除,清空,销毁,访问前驱,后继等)_双向循环链表的删除操作算法-程序员宅基地

技术标签: 数据结构  

#include "stdio.h"
#include <malloc.h>

#define OK                 1
#define ERROR              0
#define OVERFLOW          -1
#define TRUE               1
#define FALSE              0

typedef int ElemType;
typedef int Status;

typedef struct DulNode
{
	ElemType data;
	DulNode *next,*pre;
}DulNode,*DuLinkList;

Status InitList(DuLinkList &L)
{
	L = (DuLinkList)malloc(sizeof(DulNode));
	if(!L) return OVERFLOW;
	L->pre = L->next = L;
	return OK;
}

Status DestroyList(DuLinkList &L)
{
	DulNode *p,*q;
	q = p = L->next;
	while(p != L)
	{
		p = p->next;
		free(q);
		q = p;
	}
	free(L);
	L = NULL;
	
	return OK;
}

Status ClearList(DuLinkList &L)
{
	DulNode *p,*q;
	q = p = L->next;
	while(p != L)
	{
		p = p->next;
		free(q);
		q = p;
	}
	L->next = L->pre = L;
	return OK;
}

Status ListEmpty(DuLinkList &L)
{
	if(L->next == L && L->pre == L)
		return TRUE;
	else
		return FALSE;
}

int LocateElem(DuLinkList L,ElemType e,Status(*compare)(ElemType,ElemType))
{
	int i = 0;
	DulNode *p = L->next;
	while(p != L)
	{
		++i;
		if(compare(p->data,e))
			return i;
		p = p->next;
	}
	return 0;
}

Status PriorElem(DuLinkList L,ElemType cur_e,ElemType &pre_e)
{
	DulNode *p;
	p = L->next->next;
	while(p != L)
	{
		if(p->data == cur_e)
		{
			pre_e = p->pre->data;
			return TRUE;
		}
		p = p->next;
	}	
	return FALSE;
}

Status NextElem(DuLinkList &L,ElemType cur_e,ElemType &next_e)
{
	DulNode *p;

	p = L->next->next;
	while(p != L)
	{
		if(p->pre->data == cur_e)
		{
			next_e = p->data;
			return TRUE;
		}
		p = p->next;
	}
	return FALSE;
}

int ListLength(DuLinkList L)
{
	int i = 0;
	DulNode *p = L;
	while(p->next != L)
	{
		p = p->next;
		++i;
	}
	return i;
}

DulNode *GetElemP(DuLinkList L,int i)
{
	DulNode *p = L;
	int j;
	for(j = 0;j < i; ++j)
	{
		p = p->next;
	}
	return p;
}

Status GetElem(DuLinkList L,int i,ElemType &e)
{
	int j;
	DulNode *p = L;
	if(i < 0 || i > ListLength(L)) return ERROR;
	for(j = 0;j < i; ++j)
	{
		p = p->next;
	}
	e = p->data;
	return OK;
}

Status ListInsert(DuLinkList &L,int i,ElemType e)
{
	DulNode *p,*q;
	if(i < 1 || i > ListLength(L) + 1) return ERROR;
	p = GetElemP(L,i-1);

	q = (DuLinkList)malloc(sizeof(DulNode));
	if(!q) return OVERFLOW;
	
	q->next = p->next;
	p->next->pre = q;
	p->next = q;
	q->pre = p;
	q->data = e;

	return OK;
}

Status ListDelete(DuLinkList &L,int i,ElemType &e)
{
	DulNode *p;
	p = L->next;
	if(i < 0 || i > ListLength(L))
		return ERROR;
	p = GetElemP(L,i);

	p->pre->next = p->next;
	p->next->pre = p->pre;
	e = p->data;
	free(p);

	return OK;
}

void ListTraverse(DuLinkList L,void(*print)(ElemType))
{
	DulNode *p = L->next;
	while(p != L)
	{
		print(p->data);
		p = p->next;
	}
	printf("\n");
}

void ListTraverseBack(DuLinkList &L,void(*visit)(ElemType))
{
	DulNode *p = L->pre;
	while(p != L)
	{
		visit(p->data);
		p = p->pre;
	}
	printf("\n");
}

Status compare(ElemType e1,ElemType e2)
{
	if(e1 == e2)
		return TRUE;
	else
		return FALSE;
}

void print(ElemType e)
{
	printf("%d ",e);
}

int main()
{
	DuLinkList L;
	InitList(L);
	int i,n;
	Status j;
	ElemType e;
	for(i = 1; i < 5 ; ++i)
	{
		ListInsert(L,i,i);
	}
	printf("Output double link list:\n");
	ListTraverse(L,print);
	printf("Inverted order output double link list\n");
	ListTraverseBack(L,print);
	n = 2;
	ListDelete(L,n,e);
	printf("The deleted number is %d,which is %dth node:\n",e,n);
	printf("Output double link list:\n");
	ListTraverse(L,print);
	printf("Number of linklist is:%d\n",ListLength(L));
	printf("Is it empty? %d(1:YES 0:NO)\n",ListEmpty(L));
	ClearList(L);
	printf("Is it empty? %d(1:YES 0:NO)\n",ListEmpty(L));
	for(i = 1;i < 5; ++i)
	{
		ListInsert(L,i,i);
	}
	printf("Output double link list:\n");
	ListTraverse(L,print);
	n = 3;
	j = GetElem(L,n,e);
	if(j)
		printf("The %dth element of linklist is:%d\n",n,e);
	else
		printf("There is no %dth element.\n",n);
	e = 4;
	n = LocateElem(L,e,compare);
	if(n)
		printf("Equal %d number is %dth\n",e,n);
	else
		printf("There is no number\n");
	j = PriorElem(L,e,n);
	if(j)
		printf("%d pre number is %d\n",e,n);
	else
		printf("There is no precursor\n");
	j = NextElem(L,e,n);
	if(j)
		printf("%d next number is %d\n",e,n);
	else
		printf("There is no next number ater %d\n",e);
	DestroyList(L);

	return 0;
} 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zhao2018/article/details/80611019

智能推荐

数据导入到Access特别慢的解决办法-程序员宅基地

文章浏览阅读1k次。数据导入到Access有人说用事务,我在开发中用了事务还是特别慢,可能是因为Access数据库不支持批量执行SQL语句的原因吧,虽然微软建议使用ADO.NET操作数据库,但对于Access来说效率太差了,可有时候又迫不得已只能用Access,那么我们只用换一种操作数据库的方式了,这次用到了ADODB,虽然ADODB已经过时了,但它对数据库的直接操作还是要比封装好的ADO.NET快很多。下面是代码。..._excel向access追加记录 很慢 vb.net

ffmpeg下载安装教程_ffmpeg官网下载-程序员宅基地

文章浏览阅读2.1k次。ffmpeg下载安装教程_ffmpeg官网下载

内核开发基础——'make menuconfig' requires the ncurses libraries-程序员宅基地

文章浏览阅读92次。root@zhangbin-desktop-ubuntu:/usr/src/linux-headers-2.6.32-27# make menuconfig HOSTCC scripts/basic/fixdep HOSTCC scripts/basic/docproc HOSTCC scripts/basic/hash HOSTCC scripts/kconfig..._make menuconfig' requires the ncurses libraries.

Emacs之ditaa与PlantUML与dot绘图环境配置-程序员宅基地

文章浏览阅读688次。本文介绍如何使用ditaa与PlantUML与dot进行绘制流程图。ditaa与PlantUML都依赖java环境,所以事先需要有Java环境(不管我们使用的是何种OS)。Java环境的设置很简单,如果本地没有Java环境,请到Oracle官网下载之,这里就省略了。而dot绘图语言需要安装graphviz软件。本文作者使用的Windows环境..._ditaa图 plantuml

Ajax框架,DWR介绍,应用,样例-程序员宅基地

文章浏览阅读93次。使用Ajax框架1. 简化JavaScript的开发难度2. 解决浏览器的兼容性问题3. 简化开发流程经常使用Ajax框架Prototype一个纯粹的JavaScript函数库,对Ajax提供良好支持jQuery1.很优秀的JavaScript库,对Ajax提供了良好的支持2.与Prototype设计思想不同的是在使用jQuery之后,开..._dwr ajax简单介绍

如何在vue中拖动改变侧边栏div的宽度-程序员宅基地

文章浏览阅读4k次。先贴html代码<template> <div class="box-wrap"> <div class="box" id="box"></div> <div class="drag-btn" id="dragBtn" @mousedown.stop.prevent="mouseDownLeft"></div>..._vue 侧边栏拉伸宽度

随便推点

java根据IP获取当前区域天气信息-程序员宅基地

文章浏览阅读476次。java根据IP获取当前区域天气信息大致思路是客户端发起请求,我们首先根据请求获取到外网IP,然后再根据外网IP获取到用户所在城市,最后根据城市获取到天气信息获取外网IP万网获取外网IP地址: http://www.net.cn/static/customercare/yourip.asp/** * @Description:获取客户端外网ip 此方法要接入互联网才行,内网不行 **/public static String getPublicIp() { try {

python实现通讯录功能_Python 实现简单的电话本功能-程序员宅基地

文章浏览阅读1k次。#!/usr/bin/python# -*- coding: utf-8 -*-import reclass PhoneBook(object):'''这是一个电话簿脚本。该脚本能够实现AddContact:添加联系人信息ShowContact:查找姓名显示联系人SaveContacts:存储联系人到 TXT 文档(存储格式——姓名:号码/号码)LoadContacts:从 txt 文档中载入联系..._python输入电话号码按列显示

mysql添加列和索引_添加列且甚索引-程序员宅基地

文章浏览阅读3.8k次。mysql添加列 alter table to_o2o_point_record add COLUMN channel VARCHAR(64) NULL DEFAULT NULL COMMENT ‘积分渠道’; alter table to_o2o_point_record add COLUMN channel VARCHAR(64) NULL DEFAULT NULL COMMENT ‘积分渠_添加列且甚索引

初识函数-----函数的定义及用法_程序设计函数的定义是-程序员宅基地

文章浏览阅读1.9k次,点赞4次,收藏9次。初识函数-----函数的定义及用法_程序设计函数的定义是

python在医学领域应用 课程_《Python程序设计与应用》在线课程使用说明-程序员宅基地

文章浏览阅读492次。《Python程序设计与应用》在线课程使用说明网页版链接 20200223 更新一、简介本课程内容包括Python基础语法与Python应用(数据处理、可视化等)。具体章节:Python基础、内置基本数据类型、程序结构、函数、异常处理、集合与字典类型、文件操作、Python应用(科学计算numpy、pandas、matplotlib、seaborn、网络信息安全基础)。主要资源:超星MOOC平台:..._python语言程序设计与医学实践

c/c++ assert的头文件_c++ assert头文件-程序员宅基地

文章浏览阅读2.5k次。#include <iostream>#include <assert.h>using namespace std;int writestr(const char *p){ assert(0!=p);//如果p等于0,则报错误 cout<<p<<endl;}int _tmain(int argc, _TCHAR* argv[]){ char *str="hello"; writestr(str); ..._c++ assert头文件