数据结构----双向循环链表

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_41026740/article/details/83387145

CycDoubleList.h

#ifndef __CYCDOUBLELISH_H
#define __CYCDOUBLELISH_H

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<assert.h>

typedef int ElemType;

//定义双向循环链表的结点
typedef struct Node
{
	struct Node *prev;
	ElemType data;
	struct Node *next;
}Node;

typedef struct CycDoubleList
{
	Node *head; //指向头结点的指针
	int count;  //保存指针个数
}CycDoubleList, *pCycDouList;


void InitCycDoublelist(pCycDouList list); 
   
void InsertCycDoublelist(pCycDouList list, ElemType val , int pos);

void  InsertHeadCycDoublelist (pCycDouList list,ElemType val);

void InsertTailCycDoublelist(pCycDouList list,ElemType val);

void DeleteDouCycblelist(pCycDouList list,int pos);

void DeleteHeadCycDoublelist(pCycDouList list);

void DeleteTailCycDoublelist(pCycDouList list);

void DestroyCycDoublelist(pCycDouList list);

void Show1(pCycDouList list);
void Show2(pCycDouList list);

void Reverseshow(pCycDouList list);//逆序输出结点数据

#endif

CyDoubleList.c

#include"CycDoublelist.h"

//初始化链表函数
void InitCycDoublelist(pCycDouList list)
{
	assert( list != NULL);
	list->head = NULL;
	list->count = 0;
}

//(将共用的功能进行函数封装,有利于减少代码的重复出现,提高代码的利用率, 使代码更加美观的作用)
// 购买新结点空间函数            
static Node *BuyNode( ElemType val, Node *prev, Node *next)
{
	Node *s = (Node *)malloc(sizeof(Node));   //为新结点申请新空间
	assert( s != NULL);

	s->data = val;    //给新结点赋值

	if( (prev == NULL) | (next == NULL))//考虑插入的是第一个结点时的情况
	{
		s->prev = s->next = s; //如果链表中只有一个结点也要成环
	}
	else
	{
		s->prev = prev;
		s->next = next;
	}
	return s;
}

//插入结点函数
static void Insert(pCycDouList list, ElemType val, Node *p)
{
	Node *s = BuyNode(val, p, p->next);
	p->next->prev = s;
	p->next = s;
	list->count++;
}

void InsertCycDoublelist(pCycDouList list, ElemType val , int pos)
{
	assert( list != NULL);
	if( list->head == NULL)//考虑链表中无结点时的插入
	{
		Node *s = BuyNode( val, NULL, NULL);
		list->head = s;
		list->count++;
		return;
	}
	if( ( pos < 0 ) | ( pos > list->count))//判断pos的值是否有效
	{
		printf("pos is error\n");    
		return;
	}
	Node *p = list->head;
	if( pos == 0)       //    如果在双向循环链表头位置插入结点,就相当于在链表的末尾插入节点后	          
	{                   //将链表的头指针指向最后一i个结点的位置
		p = p->prev;    //找到最后一个结点的位置
		Insert(list, val, p); //将新结点插到最后一个结点的后面
		list->head = list->head->prev;  //把头指针指向新插入的结点
		return;
	}
	else
	{
		while( pos > 1)//一般情况下的结点插入
		{
			p = p->next;  //找到pos位置的结点的地址
			pos --;
		}
		Insert(list, val, p);//引用插入函数插入新结点
		return;
	}
}

//头插函数
void  InsertHeadCycDoublelist (pCycDouList list,ElemType val)
{
	InsertCycDoublelist( list, val , 0);
}
//尾插函数
void InsertTailCycDoublelist(pCycDouList list,ElemType val)
{
	InsertCycDoublelist( list,  val ,list->count);
}

//删除结点函数
void DeleteDouCycblelist(pCycDouList list,int pos)
{
	if(pos < 0 || pos > list->count)
	{
		printf("pos is error\n");
		return;
	}
	Node *p = list->head;
	if( pos == 1)//考虑如果删除的是第一个结点就得改变头指针
	{
		list->head = list->head->next; //将头指针指向删除结点前的第二个结点
	}
	while( pos > 1)
	{
		p = p->next;
		pos --;
	}
	p->next->prev = p->prev;
	p->prev->next = p->next;

	free(p);
	list->count--;
}
//删除头结点的函数
void DeleteHeadCycDoublelist(pCycDouList list)
{
	assert(list != NULL);
	DeleteDouCycblelist(list,0);
}

//删除尾结点的函数
void DeleteTailCycDoublelist(pCycDouList list)
{
	assert(list != NULL);
	DeleteDouCycblelist(list,list->count);
}

//顺序输出结点数据函数
void Show1(pCycDouList list)
{
	assert( list != NULL);
	Node *p = list->head;
	int tmp = list->count;
	while(list->count > 0)
	{
		printf("%3d",p->data);
		p = p->next;
		list->count--;
	}
	list->count = tmp;
	printf("\n");
}

void Show2(pCycDouList list)
{
	assert( list!= NULL);
	int tmp = list->count;
	Node *p = list->head;
	while( tmp > 0)
	{
		printf("%3d",p->data);
		tmp --;
	}
	printf("%3d\n",p->data);
}

//逆序输出结点数据函数
void Reverseshow(pCycDouList list)
{
	assert( list != NULL);
	Node *p = list->head;
	int tmp = list->count;
	while( list->count > 1)
	{
		p = p->next;
		list->count--;
	}
	while( list->count != tmp)
	{
		printf("%3d",p->data);
		p = p->prev;
		list->count++;
	}
	printf("%3d",p->data);
	printf("\n");
}

void DestroyCycDoublelist(pCycDouList list)
{
	assert(list != NULL);
	while(list->count != 0)
	{
		DeleteHeadCycDoublelist(list);
	}
}

main.c

#include"CycDoublelist.h"

int main()
{
	CycDoubleList list;
	InitCycDoublelist(&list);
	CycDoubleList *p = &list;

	//插入测试
	
	for( int i = 0; i < 5; i++)
	{ 
		 InsertCycDoublelist(&list, i, i);	
	}	
	printf("count1 = %d\n",p->count);

	//顺序输出测试
	Show1(&list);

	//删除测试
	for( int i = 5; i > 0; i--)
	{ 
		 DeleteDouCycblelist(&list,i);	
	}	
	printf("count1 = %d\n",p->count);
	Show1(&list);
/*
	//逆序输出测试
	Reverseshow(&list);

	//头插测试
	InsertHeadCycDoublelist (&list, 99);
	Show(&list);
	printf("count2 = %d\n",p->count);

	//尾插测试
	InsertTailCycDoublelist(&list, 88);
	Show(&list);
	Reverseshow(&list);
	printf("count3 = %d\n",p->count);
*/

return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41026740/article/details/83387145