2.2链表

1.定义单链表

#include<stdio.h>
 struct LNode {//定义单链表类型

	int data;//每个节点存放一个数据元素
	struct LNode* next;//指针指向下一个节点

}Lnode, * LinkList;

int main() {
	//起别名
	typedef struct LNode Lode;
	typedef struct LinkList *LinkList;

	Lode* L;//声明一个指向单链表第一个节点的指针
	LinkList L;//声明一个指向单链表第一个节点的指针
	return 0;
}

2.初始化单链表

/*
不带头结点的单链表
*/
#include <stdio.h>
#include <stdbool.h>  // 添加bool头文件

typedef struct LNode {
    int data;              // 数据域
    struct LNode* next;    // 指针域 指向下一个节点(修正为LNode)
} Lnode, * LinkList;

// 初始化一个空链表
bool InitList(LinkList* L) {  // 使用二级指针
    *L = NULL;  // 空表,通过解引用修改外部指针
    return true;  // 返回true
}

//判断单链表是否为空
bool Empty(LinkList L) {
    if (L==NULL)
    {
        return true;
    }
    else
    {
        return false;
    }

}

int main() {
    LinkList L;  // 声明一个指向单链表的指针
    // 初始化空链表(传入指针的地址)
    InitList(&L);

    return 0;
}

/*
带头节点的单链表
*/
#include <stdio.h>
#include <stdbool.h>  // bool头文件
#include <stdlib.h>   // malloc头文件

typedef struct LNode {
    int data;              // 数据域
    struct LNode* next;    // 指针域
} Lnode, * LinkList;

// 初始化一个空链表(带头节点)
bool InitList(LinkList* L) {  // 使用二级指针
    *L = (Lnode*)malloc(sizeof(Lnode));  // 分配一个头结点

    if (*L == NULL) {  // 内存不足,分配失败
        return false;
    }

    (*L)->next = NULL;  // 头结点之后暂时没有节点
    return true;        // 初始化成功
}

int main() {
    LinkList L;  // 声明一个指向单链表的指针
    // 初始化空链表(传入指针的地址)
    if (InitList(&L)) {
        printf("链表初始化成功\n");
    }
    else {
        printf("链表初始化失败\n");
    }

    return 0;
}

3.判断是否为空

#include<stdio.h>
//定义链表
typedef struct LNode{
	int data;//数据域
	struct LNode *next;//指针域

}Lnode,*LinkList;//节点,和 指针

//判断链表是否为空
int ListEmpty(LinkList L) {//或者Lnode *L
	if (L->next)//非空
	{
		return 0;
	}
	else {
		return 1;
	}
	
}
int main() {
	Lnode head;
	head.next = NULL;//初始化指针
	int isEmpty=ListEmpty(&head);

	printf("判断是否为空:%d\n",isEmpty);

	return 0;
}

4.单链表销毁

/*
单链表的销毁:链表销毁后不存在

思路:从头指针开始,依次释放所有节点
*/

#include<stdio.h>
#include<stdlib.h>
typedef struct LNode {
    int data;//数据域
    struct LNode* next;//指针域
}Lnode, * LinkList;//节点 和指针

//销毁单链表L
int DestroyList_L(LinkList* L) {
    Lnode* p;
    Lnode* current = *L;//解引用得到头指针

    while (current != NULL) {
        p = current;//p =L
        current = current->next;  // 正确更新遍历指针 L=L->next
        free(p);//释放当前节点
    }

    *L = NULL;//将原始头指针置为NULL
    return 0;  // 添加返回值
}

int main() {
    //初始化链表
    LinkList L = (LinkList)malloc(sizeof(Lnode));
    if (L == NULL) {
        printf("内存分配失败\n");
        return -1;
    }
    L->next = NULL;//制空链表

    DestroyList_L(&L);

    //销毁后L应该为NULL
    if (L == NULL) {
        printf("链表已经成功销毁\n");
    }
    return 0;
}

5.清空链表

/*
清空链表:
链表仍存在,但链表中无元素,成为空链表(头指针和头节点仍然存在)

思路:依次释放所有节点,并将头节点指针域设置为空
*/

#include<stdio.h>
#include<stdlib.h>
typedef struct LNode {
	int data;//数据域
	struct LNode* next;//指针域



}*LinkList,Lnode;//链表,和节点

//清空链表L
int ClearList(LinkList L) {
	Lnode* p, * q;
	p = L->next;


	while (p) {
		q = p->next;

		free(p);

		p = q;
	
	}

	L->next = NULL;

	return 0;
}
int main() {
	//初始链表
	LinkList L = (LinkList)malloc(sizeof(Lnode));

	if (L==NULL)
	{
		printf("内存分配失败!!!\n");
		
		return L;

	}
	L->next = NULL;//制空表
	ClearList(L);

	printf("链表清空成功\n");

	free(L);
	L = NULL;
	return 0;
}

6.求链表的表长

/*
* 求链表的表长
* 
* 思路:从首元节点开始,依次计数所有节点
*/

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

typedef struct LNode {
    int data;              // 数据域
    struct LNode* next;    // 指针域
} LNode, * LinkList;        // 链表节点类型,链表指针类型

int ListLength_L(LinkList L) {
    LinkList p = L->next;  // p指向第一个数据节点(跳过头节点)
    int i = 0;

    // 遍历单链表,统计节点数
    while (p != NULL) {
        i++;
        p = p->next;
    }
    return i;
}

int main() {
    // 初始化链表头节点(分配动态存储)
    LinkList L = (LinkList)malloc(sizeof(LNode));
    if (L == NULL) {
        printf("内存分配失败");
        return 1;
    }

    // 置空链表(头节点的next为NULL)
    L->next = NULL;

    // 添加测试节点
    // 创建第一个节点
    LinkList node1 = (LinkList)malloc(sizeof(LNode));
    node1->data = 10;
    node1->next = NULL;
    L->next = node1;

    // 创建第二个节点
    LinkList node2 = (LinkList)malloc(sizeof(LNode));
    node2->data = 20;
    node2->next = NULL;
    node1->next = node2;

    // 创建第三个节点
    LinkList node3 = (LinkList)malloc(sizeof(LNode));
    node3->data = 30;
    node3->next = NULL;
    node2->next = node3;

    // 测试:调用ListLength_L函数获取链表长度
    printf("链表长度: %d\n", ListLength_L(L));

    // 释放所有节点
    free(node3);
    free(node2);
    free(node1);
    free(L);
    return 0;
}

7.单链表取值

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

typedef struct LNode {
    int data;              // 数据域
    struct LNode* next;    // 指针域
} LNode, * LinkList;        // LNode是结构体类型,LinkList是指针类型

// 取值:获取单链表L中的某个数据元素的内容,通过变量e返回
int GetElem_L(LinkList L, int i, int *e) {  // 修改为指针参数
    LinkList p;
    p = L->next;
    int j = 1; // 初始化

    // 向后扫描,直到p指向第i个元素或p为空
    while (p != NULL && j < i) {
        p = p->next;
        ++j;
    }

    // 判断第i个元素是否存在
    if (!p || j > i) {  // 第i个元素不存在
        return 0;  // 返回失败
    } else {
        *e = p->data;  // 取第i个元素的值
        return 1;     // 返回成功
    }
}

int main() {
    // 初始化链表动态分配存储
    LinkList L = (LinkList)malloc(sizeof(LNode));

    // 检查内存分配是否成功
    if (L == NULL) {
        printf("内存分配失败\n");
        return 1;
    }

    // 初始化头节点
    L->data = 0;
    L->next = NULL;

    printf("链表初始化成功\n");

    int e;  // 定义用于接收数据的变量
    int result = GetElem_L(L, 10, &e);  // 传递变量地址

    if (result) {
        printf("获取元素成功,值为: %d\n", e);
    } else {
        printf("获取元素失败\n");
    }

    // 释放内存
    free(L);
    return 0;
}

8.1单链表查找——按值查找(地址)

/*
* 按值查找————根据指定数据获取该数据所在的位置(地址)
* 
* 【算法步骤】
	1.从第一个结点起,依次和e相比较。
	2.如果找到一个其值与e相等的数据元素,则返回其在链表中的
	"位置"或地址
	3.如果查遍整个链表都没有找到其值和e相等的元素,则返回0或
	"NULL"
*/

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

typedef struct LNode {
	int data;              // 数据域
	struct LNode* next;    // 指针域
} LNode, *LinkList;        // 链表节点类型,链表指针类型

// 按值查找函数:在链表L中查找值为e的节点,找到则返回节点地址,否则返回NULL
LinkList LocateElem_L(LinkList L, int e) {
	LinkList p = L->next;  // 从第一个数据节点开始查找
	
	// 遍历链表查找值为e的节点
	while (p != NULL && p->data != e) {
		p = p->next;
	}
	
	// 如果找到则返回节点地址,否则返回NULL
	return p;
}

// 辅助函数:在链表头部插入新节点
void InsertNode(LinkList L, int data) {
	LinkList newNode = (LinkList)malloc(sizeof(LNode));
	newNode->data = data;
	newNode->next = L->next;
	L->next = newNode;
}

int main() {
	// 初始化动态分配内存
	LinkList L = (LinkList)malloc(sizeof(LNode));

	// 检查内存分配是否成功
	if (L == NULL) {
		printf("内存分配失败\n");
		return 1;
	}
	
	// 初始化头节点
	L->data = 0;
	L->next = NULL;

	// 添加测试数据
	InsertNode(L, 30);  // 第1个数据节点
	InsertNode(L, 20);  // 第2个数据节点
	InsertNode(L, 10);  // 第3个数据节点

	// 测试按值查找
	int searchValue = 20;
	LinkList result = LocateElem_L(L, searchValue);
	
	if (result != NULL) {
		printf("找到值为 %d 的节点,地址为: %p\n", searchValue, result);
	} else {
		printf("未找到值为 %d 的节点\n", searchValue);
	}

	// 测试查找不存在的值
	searchValue = 50;
	result = LocateElem_L(L, searchValue);
	
	if (result != NULL) {
		printf("找到值为 %d 的节点,地址为: %p\n", searchValue, result);
	} else {
		printf("未找到值为 %d 的节点\n", searchValue);
	}

	// 释放内存
	LinkList current = L;
	while (current != NULL) {
		LinkList temp = current;
		current = current->next;
		free(temp);
	}

	return 0;
}

8.2单链表查找——按序查找(位序)

/*
* 按值查找————根据指定数据获取该数据位置序号
*
*/

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

typedef struct LNode {
    int data;              // 数据域
    struct LNode* next;    // 指针域
} LNode, *LinkList;        // 链表节点类型,链表指针类型

// 按值查找函数:在链表L中查找值为e的节点,找到则返回位置序号,否则返回0
int LocateElem_L(LinkList L, int e) {
    LinkList p = L->next;  // 从第一个数据节点开始查找(首元结点)
    int position = 1;      // 位置序号从1开始
    
    // 遍历链表查找值为e的节点
    while (p != NULL && p->data != e) {
        p = p->next;
        position++;
    }
    
    // 如果找到则返回位置序号,否则返回0
    if (p != NULL) {
        return position;
    } else {
        return 0;
    }
}

// 辅助函数:在链表尾部插入新节点
void AppendNode(LinkList L, int data) {
  
// 分配内存空间用于存储新节点
LinkList newNode = (LinkList)malloc(sizeof(LNode));
// 设置节点数据域
newNode->data = data;
// 初始化节点指针域为空
newNode->next = NULL;
    
    // 找到链表尾部
    LinkList p = L;
    while (p->next != NULL) {
        p = p->next;
    }
    
    // 在尾部插入新节点
    p->next = newNode;
}

int main() {
    // 初始化链表头节点
    LinkList L = (LinkList)malloc(sizeof(LNode));
    
    // 检查内存分配是否成功
    if (L == NULL) {
        printf("内存分配失败\n");
        return 1;
    }
    
    // 初始化头节点
    L->data = 0;
    L->next = NULL;

    // 添加测试数据
    AppendNode(L, 10);  // 第1个数据节点,值为10
    AppendNode(L, 20);  // 第2个数据节点,值为20
    AppendNode(L, 30);  // 第3个数据节点,值为30
    AppendNode(L, 40);  // 第4个数据节点,值为40

    // 测试按值查找
    int searchValue = 30;
    int position = LocateElem_L(L, searchValue);
    
    if (position != 0) {
        printf("找到值为 %d 的节点,位置序号为: %d\n", searchValue, position);
    } else {
        printf("未找到值为 %d 的节点\n", searchValue);
    }

    // 测试查找不存在的值
    searchValue = 50;
    position = LocateElem_L(L, searchValue);
    
    if (position != 0) {
        printf("找到值为 %d 的节点,位置序号为: %d\n", searchValue, position);
    } else {
        printf("未找到值为 %d 的节点\n", searchValue);
    }

    // 释放内存
    LinkList current = L;
    while (current != NULL) {
        LinkList temp = current;
        current = current->next;
        free(temp);
    }

    return 0;
}

9.单链表插入

/*
* 插入在第i个结点前插入值为e的新结点

1、首先找到
a i-1的存储位置p。
2、生成一个数据域为e的新结点s。
3、插入新结点:
 1.新结点的指针域指向结点ai;
 2.结点a;-的指针域指向新结点
*/
#include<stdio.h>
#include<stdlib.h>

typedef struct LNode {
    int data;              // 数据域
    struct LNode* next;    // 指针域
} LNode, *LinkList;        // 链表节点类型

// 在链表L的第i个位置前插入值为e的新节点
int ListInsert_L(LinkList L, int i, int e) {
    LinkList p = L;        // 从头节点开始
    int j = 0;             // 计数器初始化为0
    
    // 查找第i-1个节点,p指向i-1节点
    while (p && j < i - 1) {
        p = p->next;
        ++j;
    }
    
    // i大于表长+1或小于1,插入位置非法
    if (!p || j > i - 1) {
        return 0;  // 插入失败
    }
    
    // 生成新节点s
    LinkList s = (LinkList)malloc(sizeof(LNode));
    if (!s) {
        printf("内存分配失败\n");
        return 0;
    }
    
    s->data = e;           // 设置新节点数据,将s的数据域置为e
    s->next = p->next;     // 新节点指向原第i个节点
    p->next = s;           // 原第i-1个节点指向新节点
    
    return 1;  // 插入成功
}

// 辅助函数:在链表尾部添加节点(用于测试)
void AppendNode(LinkList L, int data) {
    LinkList newNode = (LinkList)malloc(sizeof(LNode));
    newNode->data = data;
    newNode->next = NULL;
    
    // 找到链表尾部
    LinkList p = L;
    while (p->next != NULL) {
        p = p->next;
    }
    
    // 在尾部插入新节点
    p->next = newNode;
}

// 辅助函数:打印链表
void PrintList(LinkList L) {
    LinkList p = L->next;  // 从第一个数据节点开始
    printf("链表内容: ");
    while (p != NULL) {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
}

int main() {
    // 初始化动态分配存储空间
    LinkList L = (LinkList)malloc(sizeof(LNode));
    // 检查分配内存是否成功
    if (L == NULL) {
        printf("内存分配失败");
        return 1;
    }

    // 初始化头节点
    L->data = 0;
    L->next = NULL;

    // 添加测试数据
    AppendNode(L, 10);
    AppendNode(L, 20);
    AppendNode(L, 30);
    
    printf("插入前:\n");
    PrintList(L);
    
    // 在第2个位置插入值为15的新节点
    if (ListInsert_L(L, 2, 15)) {
        printf("在第2个位置插入15成功\n");
    } else {
        printf("插入失败\n");
    }
    
    printf("插入后:\n");
    PrintList(L);
    
    // 释放内存
    LinkList current = L;
    while (current != NULL) {
        LinkList temp = current;
        current = current->next;
        free(temp);
    }

    return 0;
}

10.单链表删除

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

typedef struct LNode {
    int data;              // 数据域
    struct LNode* next;    // 指针域
} LNode, *LinkList;        // 链表节点类型

// 删除链表L的第i个节点,并将删除的值保存在e中
int ListDelete_L(LinkList L, int i, int *e) {
    LinkList p = L;        // 从头节点开始
    int j = 0;             // 计数器初始化为0
    
    // 查找第i-1个节点
    while (p && j < i - 1) {
        p = p->next;
        ++j;
    }
    
    // 如果p为空或位置不合理,返回错误
    if (!p || !p->next || j > i - 1) {
        return 0;  // 删除失败
    }
    
    // 找到要删除的节点
    LinkList q = p->next;     // q指向要删除的节点
    *e = q->data;             // 保存要删除节点的数据
    p->next = q->next;        // 让前一个节点指向后一个节点
    free(q);                  // 释放要删除节点的内存
    
    return 1;  // 删除成功
}

// 辅助函数:在链表尾部添加节点(用于测试)
void AppendNode(LinkList L, int data) {
    LinkList newNode = (LinkList)malloc(sizeof(LNode));
    newNode->data = data;
    newNode->next = NULL;
    
    // 找到链表尾部
    LinkList p = L;
    while (p->next != NULL) {
        p = p->next;
    }
    
    // 在尾部插入新节点
    p->next = newNode;
}

// 辅助函数:打印链表
void PrintList(LinkList L) {
    LinkList p = L->next;  // 从第一个数据节点开始(首元节点)
    printf("链表内容: ");
    while (p != NULL) {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
}

int main() {
    // 初始化链表头节点
    LinkList L = (LinkList)malloc(sizeof(LNode));
    if (L == NULL) {
        printf("内存分配失败\n");
        return 1;
    }

    // 初始化头节点
    L->data = 0;
    L->next = NULL;

    // 添加测试数据
    AppendNode(L, 10);
    AppendNode(L, 20);
    AppendNode(L, 30);
    AppendNode(L, 40);
    
    printf("删除前:\n");
    PrintList(L);
    
    // 删除第3个节点
    int deletedValue;
    if (ListDelete_L(L, 3, &deletedValue)) {
        printf("删除第3个节点成功,删除的值为: %d\n", deletedValue);
    } else {
        printf("删除失败\n");
    }
    
    printf("删除后:\n");
    PrintList(L);
    
    // 释放内存
    LinkList current = L;
    while (current != NULL) {
        LinkList temp = current;
        current = current->next;
        free(temp);
    }

    return 0;
}

11.1单链表建立——头插法

/*
建立单链表:头插法———元素插入链表头部,也叫前插法

1.从一个空表开始,重复读入数据;
2.生成新结点,将读入数据存放到新结点的数据域中
3.从最后一个结点开始,依次将各结点插入到链表的前端
*/

#include<stdio.h>
#include<stdlib.h>
//#define _CRT_SECURE_NO_WARNINGS         //预处理

typedef struct LNode {
    int data;              // 数据域
    struct LNode* next;    // 指针域
} LNode, * LinkList;       // 节点,链表

// 创建链表头插法
void CreateList_Head(LinkList L, int n) {
    // 不需要重新分配L的内存,使用传入的头节点
    
    for (int i = n; i > 0; i--) {
        LinkList p = (LinkList)malloc(sizeof(LNode)); // 生成新节点
        
        printf("请输入第%d个元素的值: ", n - i + 1);
        scanf("%d", &p->data); // 输入元素值
        
        /* 
         * 将节点p插入到链表L的头部位置
         */
        p->next = L->next;  // 保存当前链表的第一个有效节点(L->next)到p->next中
        L->next = p;        // 将新节点p设置为链表的第一个有效节点
    }
}

// 辅助函数:打印链表
void PrintList(LinkList L) {
    LinkList p = L->next;  // 从第一个数据节点开始
    printf("链表内容: ");
    while (p != NULL) {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
}

int main() {
    // 初始化并动态开辟存储空间
    LinkList L = (LinkList)malloc(sizeof(LNode));

    // 判断分配内存是否成功
    if (L == NULL) { 
        printf("分配内存失败");
        return 1;
    }

    // 置空数据域,指针域
    L->data = 0;
    L->next = NULL;

    CreateList_Head(L,5);  // 创建5个节点的链表
    
    PrintList(L);  // 打印链表内容

    // 释放内存
    LinkList current = L;
    while (current != NULL) {
        LinkList temp = current;
        current = current->next;
        free(temp);
    }
    
    return 0;  
}

11.2链表建立——尾插法

/*
建立单链表:尾插法元素插入在链表尾部,也叫后插法
1.从一个空表L开始,将新结点逐个插入到链表的尾部,尾指针r指向链表
的尾结点。
2.初始时,r同L均指向头结点。每读入一个数据元素则申请一个新结点,
将新结点插入到尾结点后,r指向新结点。
*/
#include<stdio.h>
#include<stdlib.h>
typedef struct LNode {
	int data;//数据域
	struct LNode* next;//指针域
}LNode,*LinkList;//节点,链表


//尾插法 正序
void CreateList_tail(LinkList L,int n) {
	LinkList r = (LinkList)malloc(sizeof(LNode));

	r = L;//尾指针指向头节点

	for (int i = 1; i <= n; i++)
	{
		LinkList p = (LinkList)malloc(sizeof(LNode));//生成新节点,输入元素值

		scanf("%d",&p->data);

		p->next = NULL;

		r->next = p;//插入到表尾
		r = p;//指向新的尾节点
	}

}

//打印链表
void PrintList(LinkList L) {
	LinkList p = L->next;  // 从第一个数据节点开始

	printf("链表内容:");
	while (p!=NULL) {
		printf("%d ",p->data);
		
		p = p->next;
	}

	printf("\n");
}
int main() {
	//初始化并动态分配内存
	LinkList L = (LinkList)malloc(sizeof(LNode));

	//判断分配内存是否成功
	if (L==NULL)
	{
		printf("内存分配失败");

		return 1;
	}

	//初始化指针域,数据域
	L->data = 0;
	L->next = NULL;

	CreateList_tail(L,5);//创建5个节点

	//打印链表内容
	PrintList(L);

	//释放内存
	free(L);
	return 0;
}

12.循环链表

/*
* 循环链表:表中最后一个元素的指针域指向头节点,整个链表形成一个环。
* 
带尾指针循环链表的合并
*/

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

typedef struct LNode {
    int data;              // 数据域
    struct LNode* next;    // 指针域
} LNode, *LinkList;

// 合并两个循环链表
LinkList Connect(LinkList Ta, LinkList Tb) {
    // 假设Ta、Tb都是非空的单循环链表
    
    LinkList p; // 不需要分配内存
    
    p = Ta->next;              // p保存Ta的头节点
    Ta->next = Tb->next->next; // Tb的尾节点指向Ta的头节点
    Tb->next->next = p;        // Tb的头节点指向Ta原来的头节点
    free(Tb);                  // 释放Tb的尾指针节点
    
    return Ta; // 返回合并后的链表
}

// 初始化循环链表
void InitCircularList(LinkList L) {
    L->next = L; // 头节点指向自己,形成循环
    L->data = 0;
}

// 在循环链表尾部插入节点
void AppendNode(LinkList rear, int data) {
    LinkList newNode = (LinkList)malloc(sizeof(LNode));
    newNode->data = data;
    
    // 新节点插入到尾节点和头节点之间
    newNode->next = rear->next; // 新节点指向头节点
    rear->next = newNode;       // 尾节点指向新节点
}

// 打印循环链表
void PrintCircularList(LinkList rear) {
    if (rear == NULL) return;
    
    LinkList head = rear->next; // 头节点
    LinkList p = head->next;    // 第一个数据节点
    
    printf("循环链表内容: ");
    while (p != head) {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
}

int main() {
    // 动态分配存储空间
    LinkList Ta = (LinkList)malloc(sizeof(LNode));
    LinkList Tb = (LinkList)malloc(sizeof(LNode));

    // 判断内存分配是否成功
    if (Ta == NULL || Tb == NULL) {
        printf("内存分配失败");
        return 1;
    }

    // 初始化循环链表
    InitCircularList(Ta);
    InitCircularList(Tb);
    
    // 为Ta添加测试数据
    AppendNode(Ta, 10);
    AppendNode(Ta, 20);
    AppendNode(Ta, 30);
    
    // 为Tb添加测试数据
    AppendNode(Tb, 40);
    AppendNode(Tb, 50);
    AppendNode(Tb, 60);
    
    printf("合并前:\n");
    printf("Ta: ");
    PrintCircularList(Ta);
    printf("Tb: ");
    PrintCircularList(Tb);

    // 合并循环链表
    LinkList result = Connect(Ta, Tb);
    
    printf("合并后:\n");
    PrintCircularList(result);

    // 释放内存
    // 需要遍历整个循环链表释放所有节点
    LinkList current = result->next; // 从第一个数据节点开始
    LinkList head = result->next;    // 记录头节点位置
    LinkList temp;
    
    do {
        temp = current;
        current = current->next;
        free(temp);
    } while (current != head);
    
    return 0;
}

13.双向链表

/*
双向链表:节点有两个指针域,一个指向直接后继,另一个指向直接前驱
*/

typedef struct DuLNode {
	int data;//数据域
	struct DuLNode* prior;//指向直接前驱
	struct DuLNode* next;//指向直接后继

}DuLNode,*DuLinkList;
#include<stdio.h>
int main() {


	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值