数据结构: 双向链表

双向链表

c 复制代码
 / /结构体定义
typedef struct Node
{
    int num;
    struct Node* pNext;
    struct Node* pPer;
}NODE;

创建一个节点

c 复制代码
 / / 创建一个节点信息
     
     / / 只是创建了一个独立节点,没有和原链表产生任何关系!
     
void creatNode()
 {
	 NODE* new_node = (NODE*)malloc(sizeof(NODE))  / / 因为&n的值无法带回有效值 故NODE n 错误
         								 / / 使用局部变量节省内存
         
      if(NULL == new_node) /  / 判空操作
      {
          perror("creatNode malloc fill!\n") / /标准库返回错误信息
              return NULL;
      }
     new_node -> num = value;
     new_node ->pNext = NULL;
     new_node ->pPer = NULL;
     
     return new_node;
 }

头插法

c 复制代码
NODE* inserthead(NODE* head,int value)
{
    NODE* new_node = createNode(value); / / 新节点创建失败!
    if(NULL == new_node)
        return head;
    
    if (head == NULL) / / 原链表空!
    {
        return new_node;
        
    }
    
    new_node ->pNext = head;
    head ->pPer = new_node;
    
    return new_node;
        
        
}

打印链表

c 复制代码
void display(NODE* head)
{
    while(head != NULL)
    {
        printf("%d",head -> num);
    head = head -> pNext;
    }
    printf("\n");
}

尾插法

C 复制代码
NODE* inserttill(NODE* head,int value)
{
	 NODE* new_node = createNode(value); 
    
	if(NULL == new_node)
        return head;
    
    if (head == NULL) 
    {
        return new_node;
        
    }
		NODE* p =head;
	while(p != NULL)
	{
		p = p -> pNext;
		
	}
	new_node = p -> pNext;
	new_node -> pNext = NULL;
	new_node -> pPer = p;
	
	return head;
}

中间插入

c 复制代码
NODE* insertmid(NODE* head, int value, int pos) {
    NODE* new_node = createNode(value);
    if (new_node == NULL) return head;  // 内存分配失败
    
    int len = getLength(head);
    
    // 处理空链表(直接返回新节点)
    if (head == NULL) {
        return (pos == 1) ? new_node : head;
    }
    
    // 头插(pos=1)
    if (pos == 1) {
        new_node->pNext = head;
        head->pPer = new_node;
        return new_node;  // 新节点成为头节点
    }
    
    // 尾插(pos等于长度+1时也视为尾插)
    if (pos == len + 1) {
        return insertTail(head, value);
    }
    
    // 中间插入(需检查pos是否合法)
    if (pos < 2 || pos > len) {
        // pos超出范围,插入失败(可根据需求调整处理方式)
        free(new_node);
        return head;
    }
    
    // 找到插入位置的前一个节点(pos-1的前驱)
    NODE* prev = head;
    for (int i = 1; i < pos - 1; i++) {  // 移动到pos-2的位置
        prev = prev->pNext;
    }
    
    // 插入新节点
    NODE* curr = prev->pNext;  // pos位置的原节点
    prev->pNext = new_node;
    new_node->pPer = prev;
    new_node->pNext = curr;
    if (curr != NULL) {
        curr->pPer = new_node;
    }
    
    return head;  // 返回头节点(头节点未改变)
}

中间插入

c 复制代码
// pos = 0 时为头插法
// 当前函数不处理头插和尾插的情况
NODE* insertMid(NODE* head, int value, int pos)
{
    NODE* new_node = createNode(value);
    if (NULL == new_node)
    {
        // 新节点创建失败
        return head;
    }

    if (head == NULL)
    {
        // 原链表为空
        return new_node;
    }

    // 获取pos位置的节点指针
    NODE* cur = currentPosNode(head, pos);
   
    // 将新节点与其插入位置之后的节点进行连接
    new_node->pNext = cur->pNext;
    cur->pNext->pPer = new_node;

    // 将新节点与其插入位置之前节点进行连接
    cur->pNext = new_node;
    new_node->pPer = cur;

    return head;
}
c 复制代码
NODE* deleteNode(NODE* head,)
{
    if(NNULL == head)
        
    {
        printf("无节点!\n");
        return NULL;
    }
    
   
    while(head != NULL && head ->num == value)
    {
        NODE* pBef = head -> pPer; / / 记录前后两个节点
        NODE* pAft = head -> pNext;
        
        / / 首节点删除
        if(pBef == NULL)
        {
            head = p1 -> pNext;
        }
        pBer ->pNext = pAft;     / / 链接两个指针
        pAft ->pPer = pBeef;
        
        
        free(p1);
        p1 = pAft;
            
    }
    
    
    if(head -> pNext == NULL)
    {
        free(head);//head = NULL;
        return NULL;
     
        
    }
    
}

尾插法

c 复制代码
NODE* insertTail(NODE* head, int value)
{
    NODE* new_node = createNode(value);
    if (NULL == new_node)
    {
        // 新节点创建失败
        return head;
    }

    if (head == NULL)
    {
        // 原链表为空
        return new_node;
    }

    // 获取尾节点
    NODE* tail = getListTail(head);

    tail->pNext = new_node;
    new_node->pPer = tail;

    return head;
}
相关推荐
Tingjct2 小时前
【初阶数据结构-二叉树】
c语言·开发语言·数据结构·算法
C雨后彩虹2 小时前
计算疫情扩散时间
java·数据结构·算法·华为·面试
飞机和胖和黄3 小时前
考研之王道C语言第三周
c语言·数据结构·考研
达文汐3 小时前
【困难】力扣算法题解析LeetCode332:重新安排行程
java·数据结构·经验分享·算法·leetcode·力扣
一匹电信狗3 小时前
【LeetCode_21】合并两个有序链表
c语言·开发语言·数据结构·c++·算法·leetcode·stl
Gorgous—l3 小时前
数据结构算法学习:LeetCode热题100-多维动态规划篇(不同路径、最小路径和、最长回文子串、最长公共子序列、编辑距离)
数据结构·学习·算法
一条大祥脚4 小时前
26.1.26 扫描线+数论|因子反演+子序列计数|树套树优化最短路
数据结构·算法
李老师讲编程5 小时前
C++信息学奥赛练习题-杨辉三角
数据结构·c++·算法·青少年编程·信息学奥赛
期末考复习中,蓝桥杯都没时间学了5 小时前
力扣刷题13
数据结构·算法·leetcode
多米Domi0116 小时前
0x3f 第48天 面向实习的八股背诵第五天 + 堆一题 背了JUC的题,java.util.Concurrency
开发语言·数据结构·python·算法·leetcode·面试