-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlist.h
144 lines (124 loc) · 2.61 KB
/
list.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/**
* @file list.h
* @author wangguibao(wang_guibao@163.com)
* @date 2021/08/29 16:58
* @brief Template functions for creating and traversing lists
*
**/
#ifndef LIST_H_INCLUDED
#define LIST_H_INCLUDED
#include <vector>
#include <functional>
template<class T> struct Node {
public:
Node(T val): value(val), next(nullptr){}
public:
T value;
Node* next;
};
/*
* create_list
* @brief Create a singly linked list from a set of elements
*
* @vec input vec
*
* @return a pointer to newly created list
*/
template<typename T>
Node<T>* create_list(const std::vector<T>& vec) {
if (vec.empty()) {
return nullptr;
}
Node<T>* head = nullptr;
Node<T>* cur = nullptr;
for (auto v: vec) {
auto* ele = new Node<T>(v);
ele->next = nullptr;
if (head == nullptr) {
head = ele;
cur = ele;
} else {
cur->next = ele;
cur = ele;
}
}
return head;
}
/*
* list_traverse
* @brief Traverse a given list. Call func on each node
*
* @param list: list head
* @param func: list traverse function
*
* @return void
*/
template<typename T>
void list_traverse(const Node<T>* list, std::function<void(T)> func) {
auto p = list;
while (p) {
func(p->value);
p = p->next;
}
}
/*
* list_destroy
* @brief destroy a list
*
* @param list: list head
*
* @return void
*/
template<typename T>
void list_destroy(const Node<T>* list) {
auto p = list;
while (p) {
auto next = p->next;
delete p;
p = next;
}
}
/*
* list_reverse
* @brief reverse a singly-linked list, returning the new list head
*
* @param list: list head
*
* @return a pointer to the new list head
*/
template<typename T>
Node<T>* list_reverse(Node<T>* list) {
Node<T>* prev = nullptr;
Node<T>* cur = list;
while (cur) {
Node<T>* temp = cur->next;
cur->next = prev;
prev = cur;
cur = temp;
}
return prev;
}
// Test case
#if 0
void print_value(int value) {
std::cout << value << std::endl;
}
int main()
{
std::vector<int> vec;
for (int i = 0; i < 10; ++i) {
vec.push_back(i);
}
auto list = create_list(vec);
std::function<void(int)> traverse_func = print_value;
std::cout << "Original list:" << std::endl;
list_traverse(list, traverse_func);
std::cout << "After reversal:" << std::endl;
auto new_head = list_reverse(list);
list_traverse(new_head, traverse_func);
list_destroy(new_head);
return 0;
}
#endif // 0
#endif // LIST_H_INCLUDED
/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */