单向循环链表和双向循环链表

单向循环链表和双向循环链表


关于顺序表、单向链表和双向链表请将鼠标移步 此处点击

1.单向循环链表

代码实现:

//#pragma once				//作为头文件时加上这行
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef int DataType;
typedef struct Node
{
	DataType data;
	struct Node *next;
}CycleLinkedList;

/*以下的第几个结点都不包括头节点,即头结点不计入下标*/

/*初始化链表,新定义的链表结点必须先初始化*/
void ListInit(CycleLinkedList* head);
/*判断链表是否非空*/
int ListNotEmpty(CycleLinkedList* head);
/*返回链表元素个数*/
int ListLength(CycleLinkedList* head);
/*在下标为i[0,size]的位置处插入一个元素x,位于该处及该处后的元素依次后移,成功返回1,失败返回0*/
int ListInsert(CycleLinkedList* head, int i, DataType x);
/*将下标为i[0,size]的位置元素删除,并把值保存在x中,位于该处元素后的元素依次前移,成功返回1,失败返回0*/
int ListDelete(CycleLinkedList* head, int i, DataType *x);
/*放问下标为i[0,size]的位置元素,并把值保存在x中,成功返回1,失败返回0*/
int ListGet(CycleLinkedList* head, int i, DataType *x);
/*撤销单链表的空间*/
void ListDestory(CycleLinkedList* head);

void ListInit(CycleLinkedList* head)
{
	head->next = head;
}

int ListNotEmpty(CycleLinkedList* head)
{
	if (head == NULL) {
		printf("头结点为NULL\n");
		return;
	}
	if (head->next == head)return 0;
	else return 1;
}

int ListLength(CycleLinkedList* head)
{
	int i = 0;
	CycleLinkedList* p = head;
	if (head == NULL) {
		printf("头结点为NULL\n");
		return;
	}
	while (p->next != head)
	{
		i++;
		p = p->next;
	}
	return i;
}

int ListInsert(CycleLinkedList* head, int i, DataType x)
{
	CycleLinkedList *p = head, *p1 = NULL;
	if (head == NULL) {
		printf("头结点为NULL\n");
		return;
	}
	/*两种情况会退出循环*/
	/*第一种是i不为0 && p->next==head退出,退出后i--,即i不为-1,也就是链表结点不足*/
	/*第二种是i为0时退出,i--后为-1,此时无论p->next是否为head,p都是所找的结点*/
	while (i-- && p->next != head)	//找到下标为i的结点的前一个结点
	{								//注意此处&&的短路规则i--应位于&&前
		p = p->next;
	}
	if (i != -1)
	{
		printf("插入参数不合法\n");
		return 0;
	}
	p1 = (CycleLinkedList*)malloc(sizeof(CycleLinkedList));
	p1->data = x;
	p1->next = p->next;
	p->next = p1;
}

int ListDelete(CycleLinkedList* head, int i, DataType *x)
{
	CycleLinkedList *p = head, *p1 = NULL;
	if (head == NULL) {
		printf("头结点为NULL\n");
		return;
	}
	while (i-- && p->next != head)	//找到下标为i的结点的前一个结点
	{
		p = p->next;
	}
	if (i != -1)
	{
		printf("删除参数不合法\n");
		return 0;
	}
	p1 = p->next;
	*x = p1->data;
	p->next = p1->next;
	free(p1);
}

int ListGet(CycleLinkedList* head, int i, DataType *x)
{
	CycleLinkedList *p = head, *p1 = NULL;
	if (head == NULL) {
		printf("头结点为NULL\n");
		return;
	}
	while (i-- && p->next != head)	//找到下标为i的结点的前一个结点
	{
		p = p->next;
	}
	if (i != -1)
	{
		printf("参数不合法\n");
		return 0;
	}
	p = p->next;
	*x = p->data;
	return 1;
}

void ListDestory(CycleLinkedList* head)
{
	CycleLinkedList *p = head->next, *p1 = NULL;
	if (head == NULL) {
		printf("头结点为NULL\n");
		return;
	}
	while (p->next != head)
	{
		p1 = p;
		p = p->next;
		free(p1);
	}
	free(p);
}

测试函数:

void test()
{
	int i, x, size;
	//也可用malloc动态申请内存,但是最后要自己调用free释放内存
	CycleLinkedList head;
	ListInit(&head);
	for (i = 0; i < 10; i++)
		ListInsert(&head, i, i);
	printf("将下标为5处的元素删除\n");
	ListDelete(&head, 5, &x);
	printf("被删除的元素为:%d\n", x);
	printf("插入元素10到下标为5处:\n", x);
	ListInsert(&head, 15, 15);	//此行插入不合法 
	ListInsert(&head, 5, 10);
	printf("将链表输出\n");
	size = ListLength(&head);
	for (i = 0; i < size; i++)
	{
		ListGet(&head, i, &x);
		printf("%d ", x);
	}
	ListDestory(&head);
}

运行结果:
在这里插入图片描述

2.双向循环链表

代码实现:

//#pragma once				//作为头文件时加上这行
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef int DataType;
typedef struct Node
{
	DataType data;
	struct Node *prior;
	struct Node *next;
}CycleDoublyList;

/*初始化链表,新定义的链表结点必须先初始化*/
void ListInit(CycleDoublyList* head);
/*判断链表是否非空,非空返回1,空返回0*/
int ListNotEmpty(CycleDoublyList* head);
/*返回链表元素个数*/
int ListLength(CycleDoublyList* head);
/*在下标为i[0,size]的位置处插入一个元素x,位于该处及该处后的元素依次后移,成功返回1,失败返回0*/
int ListInsert(CycleDoublyList* head, int i, DataType x);
/*将下标为i[0,size]的位置元素删除,并把值保存在x中,位于该处元素后的元素依次前移,成功返回1,失败返回0*/
int ListDelete(CycleDoublyList* head, int i, DataType *x);
/*放问下标为i[0,size]的位置元素,并把值保存在x中,成功返回1,失败返回0*/
int ListGet(CycleDoublyList* head, int i, DataType *x);
/*撤销单链表的空间*/
void ListDestory(CycleDoublyList* head);

void ListInit(CycleDoublyList* head)
{
	head->prior = head;
	head->next = head;
}

int ListNotEmpty(CycleDoublyList* head)
{
	if (head == NULL) {
		printf("头结点为NULL\n");
		return;
	}
	if (head->next == head)return 0;
	return 1;
}

int ListLength(CycleDoublyList* head)
{
	CycleDoublyList *p = head;
	if (head == NULL) {
		printf("头结点为NULL\n");
		return;
	}
	int i = 0;
	while (p->next != head)
	{
		i++;
		p = p->next;
	}
	return i;
}

int ListInsert(CycleDoublyList* head, int i, DataType x)
{ 
	CycleDoublyList *p = head, *p1 = NULL;
	if (head == NULL) {
		printf("头结点为NULL\n");
		return;
	}
	/*两种情况会退出循环*/
		/*第一种是i不为0 && p->next==head退出,退出后i--,即i不为-1,也就是链表结点不足*/
		/*第二种是i为0时退出,i--后为-1,此时无论p->next是否为head,p都是所找的结点*/
	while (i-- && p->next != head)	//找到下标为i的结点的前一个结点
	{								//注意此处&&的短路规则i--应位于&&前
		p = p->next;
	}
	if (i != -1)
	{
		printf("插入参数不合法\n");
		return 0;
	}
	p1 = (CycleDoublyList*)malloc(sizeof(CycleDoublyList));
	p1->data = x;
	/*下方代码 将新结点p1加到链表中,位于p后*/
	p1->next = p->next;
	p1->prior = p;
	p->next = p1;
	if (p1->next != NULL)p1->next->prior = p1;	//若插入的元素下标不是链表尾
	return 1;
}

int ListDelete(CycleDoublyList* head, int i, DataType *x)
{
	CycleDoublyList *p = head, *p1 = NULL;
	if (head == NULL) {
		printf("头结点为NULL\n");
		return;
	}
	while (i-- && p->next != head)	//找到下标为i的结点的前一个结点
	{								//注意此处&&的短路规则i--应位于&&前
		p = p->next;
	}
	if (i != -1) {
		printf("删除参数i不合法\n");
		return 1;
	}
	p1 = p->next;
	*x = p1->data;
	/*下方代码 将p1从链表中删除*/
	p->next = p1->next;
	if (p1->next != NULL)p1->next->prior = p;	//若插入的元素下标不是链表尾
	free(p1);
	return 1;
}

int ListGet(CycleDoublyList* head, int i, DataType *x)
{
	CycleDoublyList *p = head, *p1 = NULL;
	if (head == NULL) {
		printf("头结点为NULL\n");
		return;
	}
	while (i-- && p->next != head)	//找到下标为i的结点的前一个结点
	{
		p = p->next;
	}
	if (i != -1)
	{
		printf("删除参数不合法\n");
		return 0;
	}
	p1 = p->next;
	*x = p1->data;
	/*下方代码 将p1从链表中删除*/
	return 1;
}

void ListDestory(CycleDoublyList* head)
{
	CycleDoublyList *p = head->next, *p1 = NULL;
	if (head == NULL) {
		printf("头结点为NULL\n");
		return;
	}
	while (p->next != head)
	{
		p1 = p;
		p = p->next;
		free(p1);
	}
	free(p);
}

测试函数:

void test()
{
	int i, x, size;
	//也可用malloc动态申请内存,但是最后要自己调用free释放内存
	CycleDoublyList head;
	ListInit(&head);
	for (i = 0; i < 10; i++)
		ListInsert(&head, i, i);
	printf("将下标为5处的元素删除\n");
	ListDelete(&head, 5, &x);
	printf("被删除的元素为:%d\n", x);
	printf("插入元素10到下标为5处:\n", x);
	ListInsert(&head, 15, 15);	//此行插入不合法 
	ListInsert(&head, 5, 10);
	printf("将链表输出\n");
	size = ListLength(&head);
	for (i = 0; i < size; i++)
	{
		ListGet(&head, i, &x);
		printf("%d ", x);
	}
	ListDestory(&head);
}

运行结果:
在这里插入图片描述

发布了24 篇原创文章 · 获赞 11 · 访问量 5358

猜你喜欢

转载自blog.csdn.net/weixin_44339734/article/details/103235577
今日推荐