在这里记录一下我实现的双向循环链表,一些接口函数我都实现了一遍。
首先是命名为List.h的头文件
#include"iostream"
#include"string"
#include"cstdlib"
#include"cassert"
#include"cstring"
using namespace std;
//using struction to create the node of the list
#define ElemType int
typedef struct ListNode
{
ElemType data;
//if you want ot achieve the two-direction list, you must use two pointers
struct ListNode* pre;
struct ListNode* next;
};
//this function is used to compare if two string is the same
//it is mainly used to help calculate the how many elements are equal.
bool CompareStr(string str1, string str2);
class List
{
private:
ListNode* phead; // create the soilder pointer to defend the list
public:
List(); // initate the list first
void ListPushBack(ElemType pushback_value); // insert new node on the tail of the list
void ListPopBack();
void ListPushFront(ElemType pushfront_value); // insert new node on the front of the list
void ListPopFront(); // delete the value at the top of the list
void ListPrint();
bool DestoryList(); // this function is used to destory the list
bool ClearList();
ListNode* SearchList(ElemType search_value); // find the value you want to search and return the node pointer
void InsertList(ElemType insert_value, int location); // deliver the element you want to insert and the location of it
void DeleteList(int location); // delete the value which you want
int CalculateList(ElemType value_youfind); // return the number of the goal you want to find
};
List::List()
{
//remember to allocate the memory to the phead
//or your code will be error.
phead = (ListNode*)malloc(sizeof(ListNode));
phead->next = phead;
phead->pre = phead;
}
void List::ListPushBack(ElemType pushback_value)
{
ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
assert(newnode);
newnode->data = pushback_value;
ListNode* tail = phead->pre; // find the tail of the list
tail->next = newnode;
newnode->pre = tail;
newnode->next = phead;
phead->pre = newnode;
}
void List::ListPopBack()
{
//find the tail of the list
ListNode* tail = phead->pre;
ListNode* pre_tail = tail->pre;
pre_tail->next = phead;
phead->pre = pre_tail;
free(tail);
}
void List::ListPrint()
{
ListNode* cur = phead->next;
while (cur != phead)
{
cout << cur->data;
cur = cur->next;
}
cout << endl;
}
bool List::DestoryList()
{
//ListNode* cur = phead->pre; //desroty the list from the tail of the list
ListNode* head = phead->next;
ListNode* tmp = phead;
while (head->next != head)
{
//ListNode* tmp = phead;
ListNode* tail = tmp->pre;
head->pre = tail;
tail->next = head;
free(tmp);
tmp = head;
head = head->next;
}
free(head);
return true;
}
bool List::ClearList()
{
ListNode* head = phead->next;
ListNode* tmp = phead;
while (head->next != head)
{
//ListNode* tmp = phead;
ListNode* tail = tmp->pre;
head->pre = tail;
tail->next = head;
free(tmp);
tmp = head;
head = head->next;
}
phead = head;
return true;
}
ListNode* List::SearchList(ElemType search_value)
{
ListNode* cur = phead->next;
while (cur != phead)
{
if (cur->data == search_value)
{
return cur;
}
cur = cur->next;
}
return nullptr;
}
void List::InsertList(ElemType insert_value, int location)
{
ListNode* cur = phead->next;
for (int i = 0; i < location - 1; i++)
{
cur = cur->next;
}
//find the location of the node you want to insert
//There, what you should pay attention to is the location difference between two node
ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
newnode->data = insert_value;
ListNode* pre_cur = cur->pre;
pre_cur->next = newnode;
newnode->pre = pre_cur;
newnode->next = cur;
cur->pre = newnode;
}
void List::ListPushFront(ElemType pushfront_value)
{
ListNode* next_phead = phead->next;
ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
newnode->data = pushfront_value;
phead->next = newnode;
newnode->pre = phead;
newnode->next = next_phead;
next_phead->pre = newnode;
}
void List::ListPopFront()
{
ListNode* head_next = phead->next; // the node which needs to be delete
ListNode* head_next_next = head_next->next;
phead->next = head_next_next;
head_next_next->pre = phead;
free(head_next);
}
void List::DeleteList(int location)
{
ListNode* cur = phead->next;
//find the node you want to delete
for (int i = 0; i < location - 1; i++)
{
cur = cur->next;
}
ListNode* pre_cur = cur->pre;
ListNode* next_cur = cur->next;
pre_cur->next = next_cur;
next_cur->pre = pre_cur;
free(cur);
}
bool CompareStr(string str1, string str2)
{
int len1 = str1.length();
int len2 = str2.length();
if (len1 != len2)
{
return false;
}
else
{
int len = len1;
string* pstr1 = &str1;
string* pstr2 = &str2;
for (int i = 0; i < len; i++)
{
if (*pstr1 != *pstr2)
{
return false;
}
pstr1++;
pstr2++;
}
}
return true;
}
int List::CalculateList(ElemType value_youfind)
{
ListNode* cur = phead->next;
int count = 0;
while (cur != phead)
{
if (cur->data == value_youfind)
{
count++;
}
}
return count;
}
这个头文件中的类就是链表的基本实现,可以在源文件中创建链表对象然后对其进行基本的操作。下面是源文件中的实现
#include"iostream"
#include"List.h"
using namespace std;
int main()
{
//test the push element in the tail of the list
//successfully
List list;
list.ListPushBack(1);
list.ListPushBack(2);
list.ListPushBack(3);
list.ListPrint();
//test clear the list
/*list.ClearList();
list.ListPrint();
cout << endl;*/
//judge if the function is successful
//in other word, judge if the function delete the phead pointer
//successfully
list.ListPushBack(4);
list.ListPushBack(5);
list.ListPushBack(6);
list.ListPrint();
//test the function which is used to find the value and return the node
/*ListNode* find1 = list.SearchList(4);
cout << find1->data << endl;*/
//test the function which is used to delete the value which is in the tail of the list
//successfully
list.ListPopBack();
list.ListPopBack();
//list.ListPopBack();
list.ListPrint();
//test the function which is used to insert value in the postion you want
//successfully
list.InsertList(9, 2);
list.InsertList(8, 2);
list.ListPrint();
list.ListPushFront(7);
list.ListPushFront(7);
list.ListPushFront(7);
list.ListPrint();
list.ListPopFront(); // successfully
list.ListPopFront();
list.ListPopFront();
list.ListPrint();
list.DeleteList(2);
list.DeleteList(2);
list.DeleteList(2);
list.ListPrint();
//test the function which is used to desroty the list head
//means you can use the phead again unless you create the list again
bool ifDes = list.DestoryList();
cout << boolalpha << ifDes;
}
这里我分了几段代码对接口函数进行测试,下面测试的结果: