使用 VS2017 + Windows 7
偶尔当一条咸鱼,今天试一下用C++实现双向链表
--------------------------------------------------------include.h ----------------------------------------------------
-------- 有一些大佬说尽量避免头文件写到一个文件夹中,但是目前还没有找到好的书写方式
#pragma once
#ifndef __INCLUDE__
#define __INCLUDE__
#include <iostream>
#include <string>
#include <vector>
using namespace std;
#endif
---------------------------------------------------------DoubleLink.h---------------------------------------------------
-----DoubleLink.h
#pragma once
#include "include.h"
#include "test.h"
using namespace std;
typedef struct Link -- 节点
{
int item;
Link* next;
Link* prev;
};
class DoubleLink
{
private:
int length; -- 链表长度
Link* header;-- 第一个节点
Link* tail; -- 最后一个节点
public:
DoubleLink();
Link* CreateItem(); --创建内存
bool Push(int item); -- 压入到链表最后一个位置
int Pop(); -- 从取出最后一个
bool InsertItem(int index, int item);-- 插入到指定位置
int DeleteAt(int index); -- 删除指定位置
void SelectAll(); -- 打印所有节点
};
-------------------------------------------------------------DoubleLink.cpp------------------------------------------------------------
#include "DoubleLink.h"
DoubleLink::DoubleLink()
{
header = CreateItem();
tail = header;
length = 0;
}
bool DoubleLink::Push(int item) -- 压入到最后一个节点
{
Link* link = CreateItem(); -- 首先 创建一块相应的内存
if (!link) -- 如果创建失败
return false;
link->item = item;
link->prev = tail;
tail->next = link;
tail = link;
tail->next = header;
header->prev = tail;
length++;
return true;
}
int DoubleLink::Pop()
{
Link* link = header->next;
int item = 0;
for (int i = 0; i < length - 1; i++)
{
link = link->next;
}
item = link->item;
tail = link->prev;
tail->next = link->next;
length--;
free(link); -- 释放内存地址
link = NULL; -- 让他指向0x000000地址
return item;
}
Link* DoubleLink::CreateItem()
{
Link* item = (Link*)malloc(sizeof(Link)); -- 注意 我们是使用malloc创建的内存 所以应该是用free释放 而不是delete
return item;
}
bool DoubleLink::InsertItem(int index, int item)
{
if (index > length)
{
cout << "索引超出" << endl;
return false;
}
Link* link = CreateItem();
link->item = item;
Link* temp = header;
for (int i = 0; i < index; i++)
{
temp = temp->next;
}
link->prev = temp->prev; -- 和冒泡的替换差不多
link->next = temp;
temp->prev->next = link;
temp->prev = link;
length++;
return true;
}
int DoubleLink::DeleteAt(int index)
{
if (index > length || index < 1)
{
cout << "索引超出" << endl;
return false;
}
Link* link;
int data = 0;
if (index > length / 2) -- 为了节省 所以我们分为向前遍历和向后遍历
{
link = header;
for (int i = 0; i < index; i++)
{
link = link->next;
}
link->prev->next = link->next;
link->next->prev = link->prev;
data = link->item;
free(link);
link = NULL;
cout << "" << endl;
}
else
{
link = header->prev;
for (size_t i = 0; i < length - index; i++)
{
link = link->prev;
cout << "Link->Prev:" << link->item << endl;
}
link->prev->next = link->next;
link->next->prev = link->prev;
data = link->item;
free(link);
link = NULL;
}
length--;
return data;
}
void DoubleLink::SelectAll()
{
Link* link = header->next;
for (int i = 0; i < length; i++)
{
cout << link->item << endl;
link = link->next;
}
}
------------------------------------------------------------------main.cpp------------------------------------------------------------------------
#include "DoubleLink.h"
int main()
{
// 在这里 分清指针和地址的关系 地址是使用link.methodName(params object o) 访问
// 指针是用过 link->methodName(params object o) 访问
DoubleLink link;
for (int i = 0; i < 7; i++)
{
link.Push(i);
}
link.InsertItem(1, 1002);
link.SelectAll();
cout << "Pop:" << link.Pop() << endl; -- 因为我们DoubleLink.h 里面有Inclde.h的声明 所以可以直接使用 cout<<endl;
link.SelectAll();
cout << "DeleteAt:" << link.DeleteAt(7) << endl;
link.SelectAll();
system("pause");
return 0;
}