再写双向循环链表

在这里插入图片描述

#pragma once
#include<assert.h>
#include<malloc.h>
#include<stdio.h>
typedef int DLDataType;//定义链表结点结构
typedef struct DListNode{DLDataType value;struct DListNode *prev; //指向前一个结点struct DListNode *next; //指向后一个结点
} DListNode;//定义双向链表结构
typedef struct DList{DListNode *head; //表示链表头结点
}DList;DListNode *DListBuyNode(DLDataType value){DListNode *node = (DListNode *)malloc(sizeof (DListNode));node->value = value;node->next =node->prev= NULL;return node;
}//初始化
void DListInit(DList *dlist){dlist->head = DListBuyNode(0);dlist->head->next = dlist->head;dlist->head->prev = dlist->head;
}//销毁
//1. 清空链表
void DListClear(DList *dlist){DListNode *cur, *next;cur = dlist->head->next;while (cur != dlist->head){next = cur->next;free(cur);cur = next;}dlist->head->next = dlist->head->prev = dlist->head;
}//2. 彻底销毁链表
void DListDestroy(DList *dlist){DListClear(dlist);free(dlist->head);dlist->head = NULL; 
}//头插
void DListPushFront(DList *dlist, DLDataType value){DListNode *node = DListBuyNode(value);node->prev = dlist->head;node->next = dlist->head->next;dlist->head->next->prev = node;dlist->head->next = node;}//尾插
void DlistPushBack(DList *dlist, DLDataType value){DListNode *node = DListBuyNode(value);node->prev = dlist->head->prev;node->next = dlist->head;node->prev->next = node;node->next->prev = node;
}//头删
void DlistPopFront(DList *dlist){assert(dlist->head->next != dlist->head);DListNode *cur = dlist->head->next; //cur指向第一个结点dlist->head->next = cur->next;	//头结点指向第二个结点cur->next->prev = dlist->head;	//第二个结点前指针指向头结点free(cur);		//删除第一个结点
}//尾删
void DlistPopBack(DList *dlist){assert(dlist->head->next != dlist->head);    //确保链表不为空DListNode *cur = dlist->head->prev;cur->prev->next = dlist->head;cur->next->prev = cur->prev;free(cur);
}//查找
DListNode * DListFind(const DList *dlist, DLDataType value){DListNode *cur;for (cur = dlist->head->next; cur != dlist->head; cur = cur->next){if (cur->value == value){return cur;}}return NULL;
}void DListInsert(DListNode *pos, DLDataType value){DListNode *node = DListBuyNode(value);node->prev = pos->prev;node->next = pos;node->prev->next = node;pos->prev = node;
}void DListErase(DListNode *pos){pos->prev->next = pos->next;pos->next->prev = pos->prev;free(pos);
}void DListPrintf(const DList *dlist){for (DListNode *cur = dlist->head->next; cur != dlist->head; cur = cur->next){printf("%d-->", cur->value);}printf("\n");
}void TestDList(){DList list;DListInit(&list);DListPrintf(&list);DlistPushBack(&list, 1);DlistPushBack(&list, 2);DlistPushBack(&list, 3);DListPrintf(&list);DListPushFront(&list, 11);DListPushFront(&list, 12);DListPushFront(&list, 13);DListPrintf(&list);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/383178.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

链表题目--1 删除链表中所有等于val的值

注意事项 要删除的结点相邻第一个结点就是要删除的结点 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* removeElements(struct ListNode* head, int val){if(headNULL){return NULL;}struct …

链表题目--2 求链表的中间结点 和 求链表中倒数第k个结点

求链表的中间结点 思路 一个走两步&#xff0c;一个走一步。一个走到尾&#xff0c;另外一个就走到了中间 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* middleNode(struct ListNode* head…

链表题目---3 合并两个有序单链表 和 分割链表

合并两个有序单链表 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){if(l1 NULL){return l2;}else if(l2 NULL){return l1;}struc…

链表题目---4 删除链表中重复的结点 和 判断链表是否为回文链表

删除链表中重复的结点 /* struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {} }; */ class Solution { public:ListNode* deleteDuplication(ListNode* pHead){if(pHead NULL){return NULL;}ListNode *prev NULL; //用于删除的结点, 是…

链表题目----5 相交链表 和 环形链表 和 返回链表开始入环的第一个节点

相交链表 思路 链表交叉不可能是x型因为有可能两个链表不等长&#xff0c;所以我们必须让他们从同一起跑位置去起跑从同一起跑位置出发&#xff0c;依次比较每个结点的地址是否相同 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct L…

链表题目---6 复制带随机指针的链表

思路 将新结点放在老结点的后面 复制random 将链表拆开 /* // Definition for a Node. class Node { public:int val;Node* next;Node* random;Node() {}Node(int _val, Node* _next, Node* _random) {val _val;next _next;random _random;} }; */ class Solution { publi…

括号匹配问题(c和c++版本实现)

括号匹配问题 思路 遇见左括号入栈&#xff0c;遇见一个右括号弹出栈顶元素右括号入栈前如果栈已经为空&#xff0c;则不匹配如果不为空则读取并弹出&#xff0c;弹出来的元素与右括号做比较&#xff0c;必须匹配&#xff0c;不匹配返回false;如果最后栈里还有元素&#xff0c…

用队列实现栈 AND 用栈实现队列

用队列实现栈 思路 入队列就是入栈出队列的时候&#xff0c;就是把前面size-1个队列中的元素先出&#xff0c;这样最后一个元素就成队首元素了&#xff0c;再把出去的元素再次入队列读栈顶元素&#xff0c;过程和第二步是一样的&#xff0c;就是弹出后&#xff0c;再把它入队列…

最小栈的实现(设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。)

最小栈的实现 思路 两个栈&#xff0c;左边栈接受元素&#xff0c;右边栈存最小的元素入栈时&#xff0c;先入左边栈&#xff0c;随后进行比较&#xff0c;左边和右边栈顶元素进行比较&#xff0c;如果新元素小&#xff0c;就把新元素放在右边的栈顶位置&#xff0c;如果新元素…

再写循环队列----c++实现

再写循环队列 class MyCircularQueue { public:/** Initialize your data structure here. Set the size of the queue to be k. */MyCircularQueue(int k) {array (int *)malloc(sizeof(int)*k);capacity k;size 0;front 0;rear 0;}/** Insert an element into the circu…

再谈二叉树(二叉树概念,二叉树的性质,二叉树的存储结构)

树的概念 树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因 为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。它具有以下的特点&#xff1a;每个…

二叉树题目----1 前序中序后序遍历二叉树并返回相应的遍历(不是打印)

前序遍历 /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*//*** Note: The returned array must be malloced, assume caller calls free().*/ int *array; int size;void _preorde…

二叉树题目----2 检查两颗树是否相同 和 对称二叉树的判定

检查两颗树是否相同 思路 根要相等 p->val q->val左子树相等 isSameTree(p->left,q->left)右子树也要相等 isSameTree(p->right,q->right) /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* …

二叉树题目---3 另一个树的子树 AND 二叉树最大深度

另一个树的子树 思路 两个数都遍历一遍&#xff0c;找到一个根结点相同时&#xff0c;判断以这个根结点为首的二叉树是否相等 前序遍历判断两棵树是否相同对于返回值的处理是难点 bool isSameTree(struct TreeNode *p, struct TreeNode *q) {if(p NULL && q NULL)…

二叉树题目----4 前序遍历重构二叉树 AND 求二叉树中所有结点的个数

前序遍历重构二叉树 思路 整个二叉树用数组存储因为先序遍历它先遍历根&#xff0c;再遍历左&#xff0c;左边没有跑完是不会去遍历右边的&#xff0c;所以遍历左子树&#xff0c;就是数组元素每回向后一个&#xff0c;个数-1遍历右边时&#xff0c;就是数组起始位置左子树跑到…

二叉树的进阶操作---(求二叉树中所有结点个数,求叶子结点个数,求第k层结点个数;在二叉树中查找某一结点;层序遍历;判断是否为完全二叉树)

typedef struct TreeNode {struct TreeNode *left;struct TreeNode *right;char val; }TreeNode;typedef struct Result{TreeNode * root; //构建的树的根结点int used; //构建过程中用掉的val个数 } Result;求二叉树中所有结点个数 void TreeSize(TreeNode *root, int …

c++中的智能指针详解(RAII, auto_ptr的原理及其改进,unique_ptr的原理,shared_ptr的原理,shared_ptr的缺陷及其改进)

为什么需要智能指针 代码中途退出&#xff0c;也能保证资源的合理释放&#xff0c;在c中没有垃圾回收机制的情况下&#xff0c;智能指针就可以保证我们申请的资源&#xff0c;最后忘记释放的问题&#xff0c;防止内存泄露&#xff0c;也帮我们减少了一定的负担&#xff0c;不用…

二叉树题目----5 平衡二叉树 AND 根据二叉树创建字符串

平衡二叉树 /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/int MAX(int a,int b) {return a > b ? a : b; }//求高度 int getHeight(struct TreeNode *root){if(root NULL){…

再写堆(堆的性质,向下调整,建堆,堆的插入删除初始化,堆排序,TopK问题)

堆的概念 如果有一个关键码的集合K{k0,k1,k2,…,kn-1},把它的所有元素按完全二叉树的顺序存储方式存储再一个一维数组中&#xff0c;并满足:Ki<K2i1且Ki<K2i1(Ki > K2i1 且 Ki > K2i2),i0,1,2,3…。则称为小堆(或大堆)。将根结点最大的堆叫做最大堆或大根堆&#…

二叉树题目----6 二叉树的最近公共祖先 AND 二叉树搜索树转换成排序双向链表

二叉树的最近公共祖先 思路 在左、右子树中分别查找是否包含p或q&#xff1a;如果以下两种情况&#xff08;左子树包含p&#xff0c;右子树包含q/左子树包含q&#xff0c;右子树包含p&#xff09;&#xff0c;那么此时的根节点就是最近公共祖先如果左子树包含p和q&#xff0c;…