循环链表和双向链表

循环链表及其操作:
就是将尾指针指向头部:
如:#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct data {
int num;
struct data *next;
}DaTa,*Data;
//创建循环链表
Data create(int n)
{
Data p, r=NULL, q=NULL ;
int i;
for ( i = 0; i < n; i++)
{
printf(“请输入第%d个值”,i+1);
p = (Data)malloc(sizeof(Data));
scanf("%d",&p->num);
p->next = r;
if (r == NULL)
{
r = p;
}
else
{
q->next = p;
}
q = p;
}
return r;
}
//遍历循环链表
void print(Data list)
{
Data r = list;
do {
printf("%d\t",r->num);
r = r->next;
} while (r != list);
}
void main() {
Data head;
head = create(5);
print(head);
system(“pause”);
}
双链表(双向链表)及其操作:
即有两个指针域,一个指向直接前驱,一个指向直接后继
Llink Data Rlink
双向链表可以是循环的,也可以是不循环的
双向链表有一个特性,即p为指向链表中每个节点的指针,则在表达式中,有
p->llink->rlink=p->rlink->llink=p;
在这里插入图片描述
双向链表的插入与删除算法:
1.在双向循环链表中第一个数据域内容为x的节点右边插入一个数据信息为item的新节点
在这里插入图片描述
int insertd(Data list, int x, int item)
{
Data p, q;
q = list->rlink;//带头节点的双向链表
while (q != list && q->num != x)//寻找第一个满足条件的节点
{
q = q->rlink;
}
if (q == list)
{
printf(“内有满足田间的节点”);
return -1;
}
p = (Data)malloc(sizeof(DaTa));//申请一个节点
p->num = item;
p->llink = q;
p->rlink = q->rlink;
q->rlink->llink = p;
q->rlink = p;
return 1;//插入成功返回1
}
2.从带有头节点的双向链表中删除第一个数据域内容为x的节点。
在这里插入图片描述
int delect(Data list,int x)
{
Data q;
q = list->rlink;
while (q != list && q->num != x)
{
q = q->rlink;
}
if (q == list)
{
printf(“没有满足添加的头节点”);
return -1;
}
q->llink->rlink = q->rlink;
q->rlink->llink = q->llink;
free§;
return 1;
}
链表应用:1.链式存储一元多项式相加(自行理解)
2.打印文本文件的最后n行:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<string.h>
#define DEFLINES 10//n的值为10
#define MAXLEN 81//假设一行有80个字符

struct Tail {
char data[MAXLEN];
struct Tail *link;
};

void main(int argc,char *argv[])
{
int i;
char curline[MAXLEN], *filename;
int n = DEFLINES;
struct Tail *list, *ptr = NULL , *qtr=NULL;
FILE *fp;

if (argc == 3 && argv[1][0] == '-') {
	n = atoi(argv[1]+1);
	filename = argv[1];
}
else if (argc == 2)
{
	filename = argv[1];
}
else {
	fprintf(stderr,"Usage:tail [-n] filername\n");
	exit(1);
}
if ((fp = fopen(filename, "r")) == NULL)
{
	fprintf(stderr,"错误\n");
}
list = qtr = (struct Tail *)malloc(sizeof(struct Tail));
qtr->data[0] = '\0';
for ( i = 1; i < n; i++)
{
	ptr= (struct Tail *)malloc(sizeof(struct Tail));
	ptr->data[0] = '\0';
	qtr->link = ptr;
}
ptr->link = list;
ptr = list;
while (fgets(curline, MAXLEN, fp) != NULL)
{
	strcpy(ptr->data,curline);
	ptr = ptr->link;
}
	
for ( i = 0; i < n; i++)
{
	if (ptr->data[0] == '\0')
		printf("%s",ptr->data);
	ptr = ptr->link;
}
fclose(fp);

system("pause");

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
循环链表是一种将单链表尾节点的指针域置为起始节点的地址,从而形成循环连接的链表结构。这样,从链表中的任意一个节点出发,都可以遍历到链表中的所有节点。单循环链表的结构图如下所示: 双向链表是一种可以从两个方向进行遍历的链表结构,每个节点除了保存下一个节点的地址外,还保存了上一个节点的地址。双向链表的一个特点是可以利用中间的一个节点推出下一个节点和上一个节点。双向链表的结构图如下所示: 对于一个循环链表来说,不论是单向循环链表还是双向循环链表,首节点和末节点都被连接在一起。这种方式在单向和双向链表中都可以实现。要转换一个循环链表,可以选择开始于任意一个节点然后沿着列表的任一方向直到返回开始的节点。另一种方法是将循环链表的指针指向NULL来打破循环。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [数据结构——单向循环链表&双向循环链表](https://blog.csdn.net/qq_56668869/article/details/126498355)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [C语言单循环链表的表示与实现实例详解](https://download.csdn.net/download/weixin_38684892/14870959)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值