【数据结构】C语言实现带尾指针循环单链表

带尾指针循环单链表基本操作

在这里插入图片描述

定义存储结构类型

typedef struct LNode
{
	int data;
	struct LNode *next;
} LNode,*LinkList;

尾插法创建带尾指针循环单链表

//尾插法
void CreateList_R(LinkList *L,int n)   //LinkList *L L是指向尾指针
{
	LNode *p,*q;   //p是指向头结点指针  q是指向新节点指针 
	int i;
	p = q = (LinkList)malloc(sizeof(LNode));   //为头结点开辟空间,并让p、q同时指向它
	printf("为单链表输入%d个元素:",n);
	for(i=0;i<n;i++)
	{
		q->next = (LinkList)malloc(sizeof(LNode));   //第一次:头结点next指向下一个结点  第二次之后:前继结点指向新结点 
		q = q->next;   //q指针向前移,指向新结点
		scanf("%d",&q->data);
		q->next = p;    //新结点next指向头结点,形成一个循环 
		*L = q;      //尾指针指向新结点,直至链尾 
	}
}

头插法创建带尾指针循环单链表

//头插法
void CreateList_H(LinkList *LTail,int n)  //L指向尾指针L的指针(二重指针) 
{
	int i;
	*LTail = (LinkList)malloc(sizeof(LNode));   //尾结点 
	LNode *LHead = (LinkList)malloc(sizeof(LNode));    //头结点 
	(*LTail)->next = LHead;    //尾结点指针域指向头结点 
	LHead->next = *LTail;       //头结点指向尾结点 
	printf("为单链表输入%d个元素:",n);
	scanf("%d",&((*LTail)->data));   //为尾结点输入数据 
	for(i=0;i<n-1;i++)
	{
		LNode *tmp_node = (LinkList)malloc(sizeof(LNode));   //为新结点动态开辟空间单元,指针tmp_node指向新结点 
		tmp_node->next = LHead->next;    //头结点指向的后继结点赋给新插入结点的指针域 
		scanf("%d",&tmp_node->data);
		LHead->next = tmp_node;        //让头结点指向新插入结点,完成链状 
	}
}

将两个带尾指针循环单链表合并

void Union(LinkList La,LinkList Lb)   //两个链表的尾指针 
{
	LNode *tmp_node = La->next;     //先保存La链头结点指针 
	La->next = Lb->next->next;      //La链尾 连接Lb链首元结点 
	free(Lb->next);            //释放Lb链内存单元 
	Lb->next = tmp_node;           //与上一步不能颠倒,将Lb链连接La链头结点 
} 

遍历尾指针循环单链表

//遍历 
Status print(LinkList L)
{
	LNode *head;
	head = L->next;  //头结点地址 
	if(head == L) return ERROR;   //空链表(即当前头结点next域指向自己)  返回ERROR 
	while(head != L)    //当前结点指针不是尾结点指针 
	{ 
		head = head->next;        //向前移动一个接着输出数据 
		printf("%d ",head->data);    //输出数据 
	} 
	return OK;
}

测试代码

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

#define OK 1
#define ERROR 0

typedef int Status; 

typedef struct LNode
{
	int data;
	struct LNode *next;
} LNode,*LinkList;

//尾插法
void CreateList_R(LinkList *L,int n)   //LinkList *L L是指向尾指针L的指针 
{
	LNode *p,*q;   //p是指向头结点指针  q是指向新节点指针 
	int i;
	p = q = (LinkList)malloc(sizeof(LNode));   //为头结点开辟空间,并让p、q同时指向它
	printf("为单链表输入%d个元素:",n);
	for(i=0;i<n;i++)
	{
		q->next = (LinkList)malloc(sizeof(LNode));   //第一次:头结点next指向下一个结点  第二次之后:前继结点指向新结点 
		q = q->next;   //q指针向前移,指向新结点
		scanf("%d",&q->data);
		q->next = p;    //新结点next指向头结点,形成一个循环 
		*L = q;      //尾指针指向新结点,直至链尾 
	}
}

//头插法
void CreateList_H(LinkList *LTail,int n)  //L指向尾指针L的指针(二重指针) 
{
	int i;
	*LTail = (LinkList)malloc(sizeof(LNode));   //尾结点 
	LNode *LHead = (LinkList)malloc(sizeof(LNode));    //头结点 
	(*LTail)->next = LHead;    //尾结点指针域指向头结点 
	LHead->next = *LTail;       //头结点指向尾结点 
	printf("为单链表输入%d个元素:",n);
	scanf("%d",&((*LTail)->data));   //为尾结点输入数据 
	for(i=0;i<n-1;i++)
	{
		LNode *tmp_node = (LinkList)malloc(sizeof(LNode));   //为新结点动态开辟空间单元,指针tmp_node指向新结点 
		tmp_node->next = LHead->next;    //头结点指向的后继结点赋给新插入结点的指针域 
		scanf("%d",&tmp_node->data);
		LHead->next = tmp_node;        //让头结点指向新插入结点,完成链状 
	}
}

//遍历 
Status print(LinkList L)
{
	LNode *head;
	head = L->next;  //头结点地址 
	if(head == L) return ERROR;   //空链表(即当前头结点next域指向自己)  返回ERROR 
	while(head != L)    //当前结点指针不是尾结点指针 
	{ 
		head = head->next;        //向前移动一个接着输出数据 
		printf("%d ",head->data);    //输出数据 
	} 
	return OK;
}

//合并
void Union(LinkList La,LinkList Lb)   //两个链表的尾指针 
{
	LNode *tmp_node = La->next;     //先保存La链头结点指针 
	La->next = Lb->next->next;      //La链尾 连接Lb链首元结点 
	free(Lb->next);            //释放Lb链内存单元 
	Lb->next = tmp_node;           //与上一步不能颠倒,将Lb链连接La链头结点 
} 

int main()
{
	LinkList La,Lb;
	printf("------尾插法录入数据-------\n");
	CreateList_R(&La,3);
	printf("当前La链: ");
	print(La);
	printf("\n");
	printf("------头插法录入数据-------\n");
	CreateList_H(&Lb,4);
	printf("当前Lb链: "); 
	print(Lb);
	printf("\n");
	printf("----带尾指针循环链表合并-----\n");
	Union(La,Lb);
	printf("当前合链: ");
	print(Lb);
}
  • 4
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
有头节点的单链表中插入一个节点可以分为以下几个步骤: 1. 创建一个新节点,将要插入的数据存储到该节点中。 2. 找到要插入位置的前一个节点,可以使用循环遍历链表找到该节点。 3. 将新节点的 next 指针指向前一个节点的 next 指针所指向的节点。 4. 将前一个节点的 next 指针指向新节点。 下面是一个示例代码: ``` #include <stdio.h> #include <stdlib.h> // 定义链表节点 typedef struct ListNode { int val; struct ListNode *next; } ListNode; // 在有头节点的单链表中插入一个节点 void insertNode(ListNode* head, int index, int val) { // 创建新节点 ListNode* newNode = (ListNode*)malloc(sizeof(ListNode)); newNode->val = val; // 找到要插入位置的前一个节点 ListNode* prev = head; for (int i = 0; i < index && prev->next != NULL; i++) { prev = prev->next; } // 插入新节点 newNode->next = prev->next; prev->next = newNode; } // 输出链表中的所有节点 void printList(ListNode* head) { ListNode* cur = head->next; while (cur != NULL) { printf("%d ", cur->val); cur = cur->next; } printf("\n"); } int main() { // 创建有头节点的单链表 ListNode* head = (ListNode*)malloc(sizeof(ListNode)); head->next = NULL; // 在链表中插入节点 insertNode(head, 0, 1); insertNode(head, 1, 3); insertNode(head, 1, 2); insertNode(head, 3, 4); // 输出链表中的所有节点 printList(head); return 0; } ``` 在上面的示例代码中,我们定义了一个有头节点的单链表,并实现了在指定位置插入节点的功能。在 main 函数中,我们插入了四个节点,并输出了链表中的所有节点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值