算法导论之链表

来源:互联网 发布:057188158198是淘宝吗 编辑:程序博客网 时间:2024/06/01 12:30

最近在学习算法导论,为了督促自己 就把学习过程中的代码记录下来。

就先从最简单的链表写起,准确的说应该是双链表。大致先简单的介绍一下链表的优缺点,以便在后面对应的数据结构中使用该结构。

优点:链表在内存中存储并不是连续的,可以很方便的进行插入和删除操作。

缺点:由于链表的不连续存储特性,导致索引操作不能使用下标进行,因此对链表进行搜索操作时间复杂度是O(n)级别的。

以下是自己根据算法导论上面的设计书写的代码,链表的操作有插入、删除、搜索。

头文件:

//name:myList1.h#ifndef MY_LIST1_H#define MY_LIST1_H#include<iostream>#include<memory>using namespace std;template<typename T>class myList1{struct list_node{list_node* prev;T data;list_node* next;list_node(){prev = NULL;next = NULL;}list_node(list_node* node){this->data = node->data;this->prev = node->prev;this->next = node->next;}list_node(T value){this->data = value;this->next = this->prev = NULL;}};private:list_node* list_head; //链表的头//list_node* list_rear; //链表的尾int count_size; //链表中元素的个数public:myList1(){list_head = NULL;count_size = 0;}~myList1(){ }//给链表的头部插入节点xvoid insert_head(list_node* x){x->next = list_head;if (list_head != NULL)list_head->prev = x;list_head = x;x->prev = NULL;count_size++;}void insert_head(T value){//----------------------------------------------------------//此处如果使用 list_node* x=list_node(value)//表示在栈中对x分配了内存,那么后面的list_head指向x之后//当x的函数块结束,x会被释放,list_head将变成野指针//因此必须使用new在堆中进行内存分配//---------------------------------------------------------list_node* x = new list_node(value);//shared_ptr<list_node> x = make_shared<list_node>(value);insert_head(x);}//搜索链表中第一个值为value的节点,并返回该节点的指针list_node* search_first_value(T value){list_node* temp = list_head;while (temp != NULL&&temp->data != value)temp = temp->next;return temp;}//删除链表中的节点xvoid delete_list_node(list_node* x){if (x->prev != NULL)x->prev->next = x->next;elselist_head = x->next;if (x->next != NULL)x->next->prev = x->prev;count_size--;}//删除链表中第一个值为value的节点void delete_value(T value){list_node* delete_node = search_first_value(value);delete_list_node(delete_node);count_size--;}//显示链表中的数据datavoid display(){list_node* temp = list_head;while (temp != NULL){cout << temp->data << " ";temp = temp->next;}cout << endl;}};#endif

以下是测试的代码:

//name:main.c#include<vector>#include"myList1.h"int main(){vector<int> test_data = {1,2,3,4,5}; myList1<int> test_list = myList1<int>();for (int i = 0; i < test_data.size(); i++){test_list.insert_head(test_data[i]);}test_list.display();test_list.delete_value(1);test_list.display();return 0;}

本来打算自己实现一下STL中关于List源码,但是能力有限,还需继续学习才能完成,下面在给出STL中List的相关函数及功能

push_back()、push_front():把某个值插入到list的尾部或者头部。
pop_back()、pop_back():删除list中的第一个或者最后一个元素。
insert():这个方法即可以把某个元素插入到指定的位置,也可以把一个指定范围的多个元素插入到list中迭代器所指向的位置,另外还可以把某个具体的多个备份插入到list中迭代器所指定的位置。
erase():主要用来删除list中的元素,即可以删除list中某个位置的单个元素,也可以删除list中的某个范围内的所有元素对象。
clear():该函数主要用来删除list中的所有元素。

merge()函数:用于把两个list对象合并成一个list对象。

remove()函数:删除list中的对象可以使用pop_back(),pop_front(),erase()和clear()等常见函数,在list中同时提供了remove()函数,函数remove()的语法格式为void remove(const T& value)

remove会把list对象中所有等于参数的元素删除。如果list存储的是类,且类中有指针,由于remove不会自动删除类的存储空间,所以一般不能用remove方法对类元素直接删除。

remove_if():remove()函数用于无条件删除所有等于参数值的list成员元素,有时需要满足一定的条件才能把它删除,这时需要使用条件删除函数:remove_if(),函数remove的语法格式为templace<class Pred>void remove_if(Pred pr)

sort()函数:偏于list对象排序,在list成员函数中专门定义了一个成员函数sort,用于对list对象进行排序,函数sort的语法格式为void sort(); void sort(greater<T> pr)

splice()函数:merge()函数可以将两个list对象合并在一起,但是该函数不太灵活,list容器类提供了另一个函数splice。格式为void splice(iterator position, list& x); void splice(iterator position, list& x, iterator it); void splice(iterator position, list& x, iterator first, iterator last)




原创粉丝点击