(c++)创建双向链表与双向循环链表

        学会了单向链表后,学习双向链表就简单很多了。需要注意的是:双向链表的头节点和尾节点是指向NULL的,而不是尾指针指向头节点形成一个环,这一点之前博主学了单向链表后就想自己建一个双向链表,结果没憋出来。。。

        双向链表其实就是多了一个指针域,在定义结构体时多定义一个指针就好。下面直接上代码。

#include<iostream>
#include<cstdlib>//malloc()函数头文件
using namespace std;
typedef struct Node {//定义结构体
	int data;
	struct Node* prev;//头指针
	struct Node* next;//尾指针
}node;
node* create(int n) {//尾插法创建链表
	node* head = (node*)malloc(sizeof(node));//开辟内存空间
	cin >> head->data;//先将一个数据进行输入
	head->next = NULL;
	head->prev = NULL;//将头节点的头尾指针指向NULL
	node* q = head;
	for (int i = 1; i < n; i++) {
		node* p = (node*)malloc(sizeof(node));//开辟内存空间
		cin >> p->data;
		p->next = NULL;//此时尾节点其实就是p,所以要将尾节点的尾指针指向NULL
		q->next = p;
		p->prev = q;//将p的头指针指向前一个节点
		q = q->next;//将q移到p的位置,方便,下一次输入将数据插入尾部
	}
	return head;//返回头指针
}
void print(node* head) {//遍历输出链表
	node* p = head;
	while (p != NULL) {//将链表从头开始打印
		cout << p->data << " ";
		p = p->next;//指向后一个节点
	}
	cout << endl;
	p = head;
	while (p->next != NULL)p = p->next;
	node* q = p;//进行循环找到尾节点
	while (q != NULL) {//从尾节点开始倒回来输出
		cout << q->data << " ";
		q = q->prev;//指向前一个节点
	}
}
int main() {
	int n;
	cin >> n;//输入要用链表保存的数据个数
	node* head = create(n);//创建链表
	print(head);//调用函数输出
	return 0;
}

运行结果:

这代码就是简单的建立了一个双向链表并进行了简单的遍历输出,还没有开始对双向链表进行操作(删除、修改、增加)。

最后是双向循环链表,也是突发奇想(也不算是奇想吧),就想实现一下(其实就是在输入的最后将头尾连接一下,就是循环打印比较麻烦点):

#include<iostream>
#include<cstdlib>
using namespace std;
typedef struct Node {
	int data;
	struct Node* prev;//头指针
	struct Node* next;//尾指针
}node;
node* Create(int n) {
	node* head = (node*)malloc(sizeof(node));
	head->prev = NULL;
	head->next = NULL;
	cin >> head->data;//头节点也存储数据,所以先给头节点输入数据
	node* q = head, * p = NULL;;
	for (int i = 1; i < n; i++) {
		p = (node*)malloc(sizeof(node));
		cin >> p->data;
		p->next = q->next;
		p->prev = q;
		q->next = p;
		q = p;
	}
	p->next = head;//最后将链表头尾相接
	head->prev = p;
	return head;
}
void Print(node* head) {//将链表循环打印
	node* p = head;
	while (p->next != head) {
		node* q = p;
		while (q->next != p) {
			cout << q->data << " ";
			q = q->next;
		}
		cout << q->data << endl;
		p = p->next;
	}
	node* s = p;
	while (s->next != p) {
		cout << s->data << " ";
		s = s->next;
	}
	cout << s->data << endl;
}
int main() {
	int n;
	cin >> n;
	node* head = Create(n);
	cout << endl;
	Print(head);
	return 0;
}

下面这个图是运行结果:

 挺好玩的吧

  • 5
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
双向链表是一种常见的数据结构,与单向链表相比,它每个节点都有两个指针,分别指向前驱节点和后继节点。这样,双向链表可以实现向遍历,插入和删除操作也更加方便。 以下是用C语言实现双向链表的代码: ```c #include <stdio.h> #include <stdlib.h> // 双向链表节点结构体 typedef struct ListNode { int val; struct ListNode *prev; struct ListNode *next; } ListNode; // 创建双向链表节点 ListNode *createNode(int val) { ListNode *node = (ListNode *)malloc(sizeof(ListNode)); node->val = val; node->prev = NULL; node->next = NULL; return node; } // 插入节点到双向链表头部 ListNode *insertAtHead(ListNode *head, int val) { ListNode *node = createNode(val); if (head == NULL) { head = node; } else { node->next = head; head->prev = node; head = node; } return head; } // 插入节点到双向链表尾部 ListNode *insertAtTail(ListNode *head, int val) { ListNode *node = createNode(val); if (head == NULL) { head = node; } else { ListNode *cur = head; while (cur->next != NULL) { cur = cur->next; } cur->next = node; node->prev = cur; } return head; } // 删除双向链表中的节点 ListNode *deleteNode(ListNode *head, int val) { if (head == NULL) { return NULL; } ListNode *cur = head; while (cur != NULL && cur->val != val) { cur = cur->next; } if (cur == NULL) { return head; } if (cur == head) { head = head->next; if (head != NULL) { head->prev = NULL; } } else { cur->prev->next = cur->next; if (cur->next != NULL) { cur->next->prev = cur->prev; } } free(cur); return head; } // 打印双向链表 void printList(ListNode *head) { while (head != NULL) { printf("%d ", head->val); head = head->next; } printf("\n"); } // 主函数 int main() { ListNode *head = NULL; head = insertAtHead(head, 1); head = insertAtHead(head, 2); head = insertAtTail(head, 3); printList(head); // 2 1 3 head = deleteNode(head, 2); printList(head); // 1 3 head = deleteNode(head, 3); printList(head); // 1 head = deleteNode(head, 1); printList(head); // return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaoyuer2815

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值