c++实现双向单链表

所谓双链表就是除了头指针及尾指针以外,每个结点都有直接前驱和后继。

双链表就是在单链表的基础上加了一个前驱指针。

头指针无前驱但是有后继,尾指针有前驱但是无后继。

"DList.h"

#pragma once

#include <iostream>

using namespace std;

typedef int DataType;

struct Node

{

Node(const DataType& d)  //Node的构造函数,为Node初始化

:_data(d)

,_next(0)

,_prev(0)

{}

DataType _data;//数据域

Node* _next;//下一个指针

Node* _prev;//前驱

};

class DList

{

//对"<<"的重载。因在类外,应声明为友元

friend ostream& operator<<(ostream& os,const DList& s);

public:

DList()

:_head(0)

,_tail(0)

{}

~DList()

{

Node* cur = _head;

while(cur)

{

Node* del = cur;

cur = cur->_next;

delete del;

}

_head = NULL;

_tail = NULL;

}

public:

//函数声明

void PushBack(const DataType& d);//后插

void PopBack();//后删

void PushFront(const DataType& d);//前插

void PopFront();//前删

Node* Find(const DataType& d);//查找某一元素

void Insert(Node* pos,const DataType& d);//在某个位置后插入

void Reverse(DList& s);//逆序

void Sort(DList& s);//排序

void Remove(const DataType& d);//删除某一元素

void RemoveAll(const DataType& d);//删除所有d元素

void Erase(Node* pos);//删除某一位置上的元素

private:

Node* _head;//头指针

Node* _tail;//尾指针

};

//函数的实现

// 因在类外实现,所以函数处应加上域名

“DList.cpp”

#include "DList.h"

ostream& operator<<(ostream& os,const DList& s)

{

Node* cur = s._head;

while(cur)

{

os<<cur->_data<<"<=>";

cur = cur->_next;

}

os<<"over"<<endl;

return os;

}

void DList::PushBack(const DataType& d)

{

Node* newNode = new Node(d);

if(_head == NULL)

{

_head = newNode;

_tail = _head;

}

else

{

_tail->_next = newNode;

newNode->_prev = _tail;

_tail = newNode;

_tail->_next = NULL;

}

}

void DList::PopBack()

{

if(_head == NULL)

{

return;

}

else if(_head == _tail)

{

delete _head;

_head = NULL;

_tail = NULL;

}

else

{

Node* del = _tail;

_tail = _tail->_prev;

_tail->_next = NULL;

delete del;

}

}

void DList::PushFront(const DataType& d)

{

Node* newNode = new Node(d);

if(_head == NULL)

{

_head = newNode;

_tail = _head;

}

else

{

newNode->_next = _head;

_head->_prev = newNode;

_head = newNode;

}

}

void DList::PopFront()

{

if(_head == NULL)

{

return;

}

else if(_head == _tail)

{

delete _head;

_head = NULL;

_tail = NULL;

}

else

{

Node* del = _head;

_head = _head->_next;

_head->_prev = NULL;

delete del;

}

}

Node* DList::Find(const DataType& d)

{

Node* cur = _head;

while(cur)

{

if(cur->_data == d)

{

return cur;

}

cur =cur->_next;

}

return NULL;

}

void DList::Insert(Node* pos,const DataType& d)

{

Node* newNode = new Node(d);

Node* cur = _head;

if(_tail == pos)

{

_tail->_next = newNode;

newNode->_prev = _tail;

_tail = newNode;

_tail->_next = NULL;

}

else

{

while(cur)

{

if(cur == pos)

{

newNode->_next = cur->_next;

cur->_next = newNode;

}

cur = cur->_next;

}

}

}

void DList::Reverse(DList& s)

{

if(_head == NULL)

return;

else if(_head == _tail)

return;

else

{

Node* cur = _tail;

while(cur)

{

cout<<cur->_data<<"<=>";

cur = cur->_prev;

}

}

}

void DList::Sort(DList& s)

{

if(s._head == NULL)

return;

else if(s._head == s._tail)

return;

else

{

Node* cur = NULL;

Node* ret = NULL;

DataType tmp = 0;

while(s._head != ret)

{

cur = s._head;

while(cur&&(cur->_next != ret))

{

if(cur->_data > cur->_next->_data)

{

tmp = cur->_data;

cur->_data = cur->_next->_data;

cur->_next->_data = tmp;

}

cur = cur->_next;

}

ret = cur;

}

}

}

void DList::Remove(const DataType& d)

{

Node* cur = _head;

Node* tmp = NULL;

Node* del = NULL;

Node* newNode = NULL;

if(_head == NULL)

return;

while(cur)

{

if(cur->_data == d)

{

del = cur;

if(cur == _head)

{

_head = _head->_next;

_head->_prev = NULL;

delete del;

return;

}

else

{

tmp->_next = cur->_next;

cur->_next->_prev = tmp;

cur = tmp->_next;

delete del;

return;

}

}

tmp = cur;

cur = cur->_next;

}

}

void DList::RemoveAll(const DataType& d)

{

Node* cur = _head;

Node* tmp = NULL;

Node* del = NULL;

Node* newNode = NULL;

if(_head == NULL)

return;

while(cur)

{

if(cur->_data == d)

{

del = cur;

if(cur == _head)

{

_head = _head->_next;

_head->_prev = NULL;

cur = _head;

}

else

{

tmp->_next = cur->_next;

cur->_next->_prev = tmp;

cur = tmp->_next;

}

delete del;

}

else

{

tmp = cur;

cur = cur->_next;

}

}

}

void DList::Erase(Node* pos)//删除某一位置

{

Node* cur = _head;

Node* del = NULL;

if(pos == _head)

{

del = _head;

_head = _head->_next;

_head->_prev = NULL;

delete del;

}

else if(pos == _tail)

{

del = _tail;

_tail = _tail->_prev;

_tail->_next = NULL;

delete del;

}

else

{

while(cur)

{

if(cur->_next == pos)

{

del = cur->_next;

cur->_next = pos->_next;

pos->_next->_prev = cur;

delete del;

}

cur = cur->_next;

}

}

}

#include "DList.h"

ostream& operator<<(ostream& os,const DList& s)

{

Node* cur = s._head;

while(cur)

{

os<<cur->_data<<"<=>";

cur = cur->_next;

}

os<<"over"<<endl;

return os;

}

void DList::PushBack(const DataType& d)

{

Node* newNode = new Node(d);

if(_head == NULL)

{

_head = newNode;

_tail = _head;

}

else

{

_tail->_next = newNode;

newNode->_prev = _tail;

_tail = newNode;

_tail->_next = NULL;

}

}

void DList::PopBack()

{

if(_head == NULL)

{

return;

}

else if(_head == _tail)

{

delete _head;

_head = NULL;

_tail = NULL;

}

else

{

Node* del = _tail;

_tail = _tail->_prev;

_tail->_next = NULL;

delete del;

}

}

void DList::PushFront(const DataType& d)

{

Node* newNode = new Node(d);

if(_head == NULL)

{

_head = newNode;

_tail = _head;

}

else

{

newNode->_next = _head;

_head->_prev = newNode;

_head = newNode;

}

}

void DList::PopFront()

{

if(_head == NULL)

{

return;

}

else if(_head == _tail)

{

delete _head;

_head = NULL;

_tail = NULL;

}

else

{

Node* del = _head;

_head = _head->_next;

_head->_prev = NULL;

delete del;

}

}

Node* DList::Find(const DataType& d)

{

Node* cur = _head;

while(cur)

{

if(cur->_data == d)

{

return cur;

}

cur =cur->_next;

}

return NULL;

}

void DList::Insert(Node* pos,const DataType& d)

{

Node* newNode = new Node(d);

Node* cur = _head;

if(_tail == pos)

{

_tail->_next = newNode;

newNode->_prev = _tail;

_tail = newNode;

_tail->_next = NULL;

}

else

{

while(cur)

{

if(cur == pos)

{

newNode->_next = cur->_next;

cur->_next = newNode;

}

cur = cur->_next;

}

}

}

void DList::Reverse(DList& s)

{

if(_head == NULL)

return;

else if(_head == _tail)

return;

else

{

Node* cur = _tail;

while(cur)

{

cout<<cur->_data<<"<=>";

cur = cur->_prev;

}

}

}

void DList::Sort(DList& s)

{

if(s._head == NULL)

return;

else if(s._head == s._tail)

return;

else

{

Node* cur = NULL;

Node* ret = NULL;

DataType tmp = 0;

while(s._head != ret)

{

cur = s._head;

while(cur&&(cur->_next != ret))

{

if(cur->_data > cur->_next->_data)

{

tmp = cur->_data;

cur->_data = cur->_next->_data;

cur->_next->_data = tmp;

}

cur = cur->_next;

}

ret = cur;

}

}

}

void DList::Remove(const DataType& d)

{

Node* cur = _head;

Node* tmp = NULL;

Node* del = NULL;

Node* newNode = NULL;

if(_head == NULL)

return;

while(cur)

{

if(cur->_data == d)

{

del = cur;

if(cur == _head)

{

_head = _head->_next;

_head->_prev = NULL;

delete del;

return;

}

else

{

tmp->_next = cur->_next;

cur->_next->_prev = tmp;

cur = tmp->_next;

delete del;

return;

}

}

tmp = cur;

cur = cur->_next;

}

}

void DList::RemoveAll(const DataType& d)

{

Node* cur = _head;

Node* tmp = NULL;

Node* del = NULL;

Node* newNode = NULL;

if(_head == NULL)

return;

while(cur)

{

if(cur->_data == d)

{

del = cur;

if(cur == _head)

{

_head = _head->_next;

_head->_prev = NULL;

cur = _head;

}

else

{

tmp->_next = cur->_next;

cur->_next->_prev = tmp;

cur = tmp->_next;

}

delete del;

}

else

{

tmp = cur;

cur = cur->_next;

}

}

}

void DList::Erase(Node* pos)//删除某一位置

{

Node* cur = _head;

Node* del = NULL;

if(pos == _head)

{

del = _head;

_head = _head->_next;

_head->_prev = NULL;

delete del;

}

else if(pos == _tail)

{

del = _tail;

_tail = _tail->_prev;

_tail->_next = NULL;

delete del;

}

else

{

while(cur)

{

if(cur->_next == pos)

{

del = cur->_next;

cur->_next = pos->_next;

pos->_next->_prev = cur;

delete del;

}

cur = cur->_next;

}

}

}

//函数测试

“test.cpp”

#include "DList.h"

void Test1()

{

DList l1;

/*l1.PushBack(1);

l1.PushBack(2);

l1.PushBack(3);

l1.PushBack(4);

cout<<l1;

l1.PopBack();

l1.PopBack();

cout<<l1;

l1.PopBack();

l1.PopBack();

cout<<l1;*/

l1.PushFront(1);

l1.PushFront(2);

l1.PushFront(3);

l1.PushFront(4);

cout<<l1;

l1.PopFront();

l1.PopFront();

cout<<l1;

l1.PopFront();

l1.PopFront();

l1.PopFront();

cout<<l1;

}

void Test2()

{

DList l1;

l1.PushBack(1);

l1.PushBack(2);

l1.PushBack(3);

l1.PushBack(4);

cout<<l1;

Node* ret = l1.Find(3);

if(ret != NULL)

{

cout<<ret->_data<<endl;

}

else

{

cout<<"链表中无此元素"<<endl;

}

//l1.Insert(ret,5);

l1.Erase(ret);

cout<<l1;

}

void Test3()

{

DList l1;

l1.PushBack(1);

l1.PushBack(7);

l1.PushBack(1);

l1.PushBack(5);

l1.PushBack(4);

l1.PushBack(1);

l1.PushBack(0);

cout<<l1;

//l1.Reverse(l1);

/*l1.Sort(l1);

cout<<l1;*/

l1.Remove(4);

l1.RemoveAll(1);

cout<<l1;

}

int main()

{

Test2();

return 0;

}

时间: 2024-12-11 18:19:50

c++实现双向单链表的相关文章

双向单链表

//函数声明部分:#include"twowaylinklist.h" #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> typedef int ElemType; typedef struct DulNode { struct DulNode *prior; ElemType data; struct DulNode *next; }DulNode; void judg

【算法设计-链表】单链表与双向循环链表

1.单链表代码:包含了尾插法,插入,删除操作. 有头结点的单链表也是为了在第一个位置插入和删除时候容易,不需要另外讨论 #include<stdio.h> #include<stdlib.h> typedef struct Linklist { int key; Linklist *next; }Linklist; Linklist* create_end() { Linklist *head=(Linklist *)malloc(sizeof(Linklist)); Linkli

线性单链表

昨天提到了用线性单链表实现直接插入排序,所以准备借此复习一下线性单链表的内容......(很惭愧,两个学期没再摸数据结构,记不得了) 线性单链表是一种非随机存取的存储结构.因为与顺序表不同的是,链表结构中结点的位置不是连续的,需要通过链表中的结构指针来单向指引(如果是双向链表,则是双向指引.) 链表中的结点,由两个部分构成,一个是数据域,一个是指针域.指针域可以有一到两个,其中存储的指针,既有指向直接前驱的,也有指向直接后继的.在单链表中,只有指向直接后继的指针. 单链表由头指针开始,头指针指向

STL源码笔记(16)—单链表slist

STL单链表slist简介 概述 slist(Single linked list)顾名思义,是一个单向链表,这个容器并不在标准规格之内,在我几年的代码学习生涯中也是第一次听说,既然侯老师的书中提到了,那也还是学习一蛤. slist与list的主要差别是,前者的迭代器属于单向的Forward Iterator(可读写),后者的迭代器属于双向的Bidirectional Iterator(可以双向读写).看起来slist的功能应该会不如list,但由于其单向链表的实现,其消耗的空间更小,某些操作更

一起talk C栗子吧(第十二回:C语言实例--单链表一)

各位看官们,大家好,从今天开始,我们讲大型章回体科技小说 :C栗子,也就是C语言实例.闲话休提, 言归正转.让我们一起talk C栗子吧! 看官们,上一回中咱们没有说具体的例子,而且是说了例子中的文件组织结构.这一回咱们继续说C例子, 说的例子是链表,更准确的说法叫作单链表.咱们不但要说C例子,而且会在例子中使用上一回中说过的 文件组织结构,就当作是举例说明文件组织结构的使用方法. 有点一石二鸟的感觉,哈哈. 链表定义 看官们,所谓的链表其实就是一组元素通过一定的方式链接在一起.比如我们坐的火车

深度解析(三)数组、单链表和双链表

数组.单链表和双链表介绍 以及 双向链表的C/C++/Java实现 概要 线性表是一种线性结构,它是具有相同类型的n(n≥0)个数据元素组成的有限序列.本章先介绍线性表的几个基本组成部分:数组.单向链表.双向链表:随后给出双向链表的C.C++和Java三种语言的实现.内容包括:数组单向链表双向链表1. C实现双链表2. C++实现双链表3. Java实现双链表 数组 数组有上界和下界,数组的元素在上下界内是连续的. 存储10,20,30,40,50的数组的示意图如下: 数组的特点是:数据是连续的

单链表的python实现

首先说下线性表,线性表是一种最基本,最简单的数据结构,通俗点讲就是一维的存储数据的结构. 线性表分为顺序表和链接表: 顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素,称为线性表的顺序存储结构或顺序映像: 链式表示指的是用一组任意的存储单元存储线性表中的数据元素,称为线性表的链式存储结构.而他既可以是连续的也可以不连续,是通过一个与后继结点的连接信息构建起来的. *顺序表(这个不是本次重点,简单介绍一下) 顺序表是用一段连续的存储单元依次存储数据元素,查找元素是很方便的,但是如果要

线性表——顺序表与单链表学习小结

线性表 线性表(linear list)是n个具有相同特性的数据元素的有限序列. 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表.链表.栈.队列.字符串... 线性表在逻辑上是线性结构,也就说是连续的一条直线.但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储. 顺序表 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储.在数组上完成数据的增删查改. 链表 链表是一种物理存储结构上非连续.非顺序的存储结构,数据

使用OC实现单链表:创建、删除、插入、查询、遍历、反转、合并、判断相交、求成环入口

一.概念 链表和数组都是一种线性结构,数组有序存储的,链表是无序存储的. 数组中的每一个元素地址是递增或者递减的关系,链表的每一个节点的地址没有此规律,它们是通过指针的指向连接起来. 链表种类:单链表.双向链表.循环链表.双向循环链表 单链表:一个数据域data.一个后继指针域next.也即:上一个节点指向下一个节点,尾节点指向空. 双向链表:一个数据域data.一个前驱指针域previous.一个后继指针域next.也即:上一个节点和下一个节点互相指向,尾节点指向空. 循环链表:一个数据域da