您的位置:首页 > 其它

双向链表的基本操作

2014-11-16 23:20 344 查看
主要实现了双向链表的在尾部插入,在指定位置插入,前序遍历和后序遍历,以及删除指定节点和删除匹配数据的节点。因为在Windows下使用VS调试用CB写的C代码产生太多问题,因此使用了C++,但是没有使用太多C++的特性,应该很容易移植到C编译器下。

下面是全部代码

DouNode.cpp

#include "iostream"
#include "stdlib.h"

/*宏函数*/
#define log(data) std::cout<<data<<std::endl

#define isNull(ptr);\
{\
if(ptr==nullptr){\
log("链表为空");\
return; }\
}\

typedef struct _node_
{
int data;
struct _node_ *pre;
struct _node_ *next;
}node;

/*在尾部加入新节点*/
void addToTail(node *&head,node *&tail, int data)
{
node *p = (node *)malloc(sizeof(node));
p->data = data;
p->pre = nullptr;
p->next= nullptr;
if (tail == nullptr)
{
head = p;
tail = p;
}
else
{
p->pre = tail;
tail->next = p;
tail = p;
}
}

/*指定位置插入*/
void insertByIndex(node *&head, node *&tail, int index, int data)
{
node *tmp,*bak = head;/*备份头部*/

int num = 1;

node *p = (node *)malloc(sizeof(node));
p->data = data;
p->pre = nullptr;
p->next = nullptr;

if (head == nullptr)
{
if (index == 1)
{
head = tail = p;
}
else
{
free(p);
std::cout << "链表为空,仅支持从索引 1 处插入数据" << std::endl;
}
return;
}

while (head != tail && index != num)
{
head = head->next;
++num;
}

if (index != num)
{
std::cout << "索引越界" << std::endl;
free(p);
head = bak;
return;
}

p->pre = head->pre;
p->next = head;
head->pre->next = p;
head->pre = p;

head = bak;
}

/*前序遍历*/
void forDisplay(node *head,node *tail)
{
isNull(head);
while (head != tail)
{
std::cout << head->data << std::endl;
head=head->next;
}
std::cout << head->data << std::endl;
std::cout << "==END==" << std::endl;
}

/*倒序遍历*/
void backDisplay(node *head, node *tail)
{
isNull(head);
while (tail!=head)
{
std::cout << tail->data << std::endl;
tail = tail->pre;
}
std::cout << tail->data << std::endl;
std::cout << "==END==" << std::endl;
}

/*删除第一个匹配的节点*/
void deleteData(node *&head, node *&tail,int data)
{
isNull(head);
node *tmp, *bak = head;
if (head->data == data)
{
tmp = head;
head = head->next;
free(tmp);
return;
}
head = head->next;
while (head != tail && head->data!=data)
{
head = head->next;
}

if (head->next==nullptr)
{
tmp = tail;
tail = tail->pre;
tail->next = nullptr;
free(tmp);
}
else
{
head->pre->next = head->next;
head->next->pre = head->pre;
free(head);
}
head = bak;
}

/*删除指定位置的节点*/
void deleteByIndex(node *&head, node *&tail, int index)
{
isNull(head);
node *tmp, *bak = head;
int num = 2;
if (index == 1)
{
tmp = head;
head = head->next;
free(tmp);
return;
}
head = head->next;
while (head != tail && index != num)
{
++num;
head = head->next;
}

if (index != num)
{
std::cout << "索引越界,最大应为"<< num << std::endl;
head = bak;
return;
}

if (head->next == nullptr)
{
tail = tail->pre;
tail->next = nullptr;
free(head);
head = bak;
return;
}

head->pre->next = head->next;
head->next->pre = head->pre;
free(head);
head = bak;
}

int main(void)
{
node *head=nullptr;
node *tail = nullptr;

addToTail(head, tail, 1);
addToTail(head, tail, 2);
addToTail(head, tail, 3);
addToTail(head, tail, 4);
addToTail(head, tail, 5);

insertByIndex(head, tail, 2, 123);
forDisplay(head, tail);

deleteByIndex(head, tail, 3);
forDisplay(head, tail);
system("pause");
return 0;
}


因为想到的可能有限,因此测试出的结果可能有某些问题,望读者发现后不吝指教。

以上。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: