单向循环链表和双向循环链表
关于顺序表、单向链表和双向链表请将鼠标移步
此处点击
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);
}
运行结果: