建立带头结点的双向链表_尾插法

// -------------------------------------------------------
//2014--03--14
// 建立双向链表
// 程序分析:双向链表的节点有两个指针域,一个指向直接前驱,另一个指向直接后继。
//         其中第一个节点的前驱指针为NULL ,最后一个节点的直接后继指针为NULL ;
// -------------------------------------------------------

#include <stdio.h>
#include <time.h>
#include <malloc.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
// -------------------------------------------------------
//*******************************************************
// 结构名:DouLNode ;
// 结构说明:该结构为双向链表的节点结构 ,其中有两个指针,一个关键字
// 参数说明:data 关键字
//		   prior 指向直接前驱的指针 
//         next 指向后继节点的指针
//*******************************************************
struct DouLNode 
{
	int data;
	DouLNode *prior;
	DouLNode *next ;
};
// -------------------------------------------------------
//*******************************************************
// 函数名:DouLinkCreate();
// 函数功能:建立一个双向链表,
// 参数说明:head 为一个指向双向链表头节点的指针 
//         size 为双向链表节点的个数
// 注意:这里的双向链表带有头结点,利用的是尾插法。
//*******************************************************
void DouLinkCreate(DouLNode *&head , int size )
{
	// 建立第一个节点,配置节点记忆体
	head = (DouLNode*)malloc(sizeof(DouLNode) );
	head->data = 0 ;
	head->prior= NULL ;
	head->next = NULL ;

	DouLNode * p = head;  // 指向头结点

	for (int i =0;i<size ;++ i)
	{
		DouLNode* q = (DouLNode*)malloc(sizeof(DouLNode) );
		q->data = i+1;
		q->next = NULL ;

		q->prior = p;
		p->next = q ;

		p = q ;
	}

}
// -------------------------------------------------------
int main()
{
	DouLNode * head ;
	DouLinkCreate(head ,10 );

	DouLNode * p = head ;
	DouLNode * q = NULL ;
	p = p->next ;
	while (p != NULL )
	{
		cout << p->data << endl; // 从前往后输出
		q = p ;
		p = p->next ;
	}

	cout << endl;
	while (q != head  )
	{
		cout << q->data << endl; // 从后往前输出
		q = q->prior ;
	}

	return 0;
}
// -------------------------------------------------------

在删除带头结点的双向链表的第i个节点时,首先要明白带头结点的链表的结构。带头结点的双向链表一个特殊节点,即头结点,它不存储有效数据,但链接了链表的第一个和最后一个元素。第i个节点是指从头结点开始计数的第i个节点,即不包括头结点本身。 删除第i个节点的一般步骤如下: 1. 检查i的有效性:确保i的值在链表的范围内(1 <= i <= 链表长度)。 2. 寻找第i个节点:从头结点出发,遍历链表直到找到第i个节点。由于带头结点,实际上我们需要找到第i+1个节点。 3. 调整指针: - 如果第i个节点存在,调整其前驱节点和后继节点的指针,使它们跳过第i个节点,直接相连。 - 如果第i个节点是第一个有效节点(即i=1),需要调整头结点的指针指向第二个节点。 4. 删除节点:释放第i个节点所占用的内存空间。 5. 更新链表长度:如果需要的话,更新链表中元素的数量。 这是一个简单的代码框架,展示删除操作的逻辑: ```c typedef struct Node { int data; struct Node* prev; struct Node* next; } Node; void deleteNodeAtPosition(Node* head, int position) { if (position < 1 || head == NULL) return; // 检查i的有效性 Node* current = head; for (int i = 0; i < position && current != NULL; ++i) { current = current->next; } if (current == NULL) return; // 如果没有找到第i个节点,则返回 Node* prevNode = current->prev; Node* nextNode = current->next; if (prevNode != NULL) { prevNode->next = nextNode; // 前驱节点指向后继节点 } else { // 如果要删除的是第一个有效节点,则需要更新头结点 head = nextNode; } if (nextNode != NULL) { nextNode->prev = prevNode; // 后继节点指向前驱节点 } free(current); // 释放内存 } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值