在我的資料結構課程中,我收到了一個非常常見的反轉鏈表的問題。我已經在網上看到并閱讀了足夠多的內容,以便對如何操作有一個好主意。然而,教授為我提供了這個代碼片段來實作我的功能:
template<class T>
void Reverse(LinkedList<T> &array) {
//my code here
}
我希望提供的骨架代碼像
void reverse(struct node **head_ref) {
}
為什么到底有一個陣列參考被傳遞給函式?我應該如何實施?這是一個錯字嗎?
uj5u.com熱心網友回復:
我看到很多關于鏈表的問題,人們主要在談論節點。但是鏈表不是節點。它具有或包含節點,或者更好地說是指向頭節點的指標。
因此,如果您了解資料結構,那么您需要了解這個根本區別。
在 C 中,您甚至可以在“LinkedList”類中??嵌入“Node”類。然后定義一個指標,指向鏈表中名稱為head的型別“Node”。
關于您對函式原型的問題。
第一,你對“陣列”這個詞感到困惑。該函式使用型別為LinkedList Reference的變數呼叫,形式引數名稱為“array”(然后是對“Linked”List 的參考。
這將在函式中反轉,結果再次出現在給函式的 LinkedList 中。
您預期的原型“void reverse(struct node **head_ref)”是錯誤的,因為您想要反轉完整的鏈表,而不是“節點”。
因為您沒有顯示類“LinkedList”的定義,所以這里無法顯示實作細節。我只能告訴你通常的簡單演算法。您使用節點中的 next/previos 指標從開始和結束同時遍歷鏈表。然后簡單地從前端和末端從當前對中“交換”節點中的值。
你可以在這里看到一個潛在的實作
您可以在下面找到具有內置反向功能的鏈表示例
#include <iostream>
#include <iterator>
#include <vector>
#include <type_traits>
#include <initializer_list>
#include <algorithm>
#include <list>
// ------------------------------------------------------------------------------------------------
// This would be in a header file -----------------------------------------------------------------
// Type trait helper to identify iterators --------------------------------------------------------
template<typename T, typename = void>
struct is_iterator { static constexpr bool value = false; };
template<typename T>
struct is_iterator<T, typename std::enable_if<!std::is_same<typename std::iterator_traits<T>::value_type, void>::value>::type> {
static constexpr bool value = true;
};
// The List class ---------------------------------------------------------------------------------
template <typename T>
class List {
// Sub class for a Node -----------
struct Node {
Node* next{};
Node* previous{};
T data{};
Node(Node* const n, Node* const p, const T& d) : next(n), previous(p), data(d) {}
Node(Node* const n, Node* const p) : next(n), previous(p) {}
Node() {}
};
// Private list data and functions --------
size_t numberOfElements{};
Node* head{};
void init() { head = new Node(); head->next = head; head->previous = head; numberOfElements = 0; }
public:
struct iterator; // Forward declaration
// Constructor --------------------
List() { init(); }
explicit List(const size_t count, const T& value) { init(); insert(begin(), count, value); };
explicit List(const size_t count) { init(); insert(begin(), count); }
template <typename Iter>
List(const Iter& first, const Iter& last) { init(); insert(begin(),first, last); }
List(const List& other) { init(), insert(begin(), other.begin(), other.end()); };
List(List&& other) : head(other.head), numberOfElements(other.numberOfElements) { other.init(); }
List(const std::initializer_list<T>& il) { init(); insert(begin(), il.begin(), il.end()); }
template <int N> List(const T(&other)[N]) { init(); insert(begin(), std::begin(other), std::end(other)); }
template <int N> List(T(&other)[N]) { init(); insert(begin(), std::begin(other), std::end(other)); }
// Assignment ---------------------
List& operator =(const List& other) { clear(); insert(begin(), other.begin(), other.end()); return *this; }
List& operator =(List&& other) { clear(); head = other.head; numberOfElements = other.numberOfElements; other.init(); return *this; }
List& operator =(const std::initializer_list<T>& il) { clear(); insert(begin(),il.begin(),il.end()); return *this; }
template <int N> List& operator =(const T(&other)[N]) { clear(); insert(begin(), std::begin(other), std::end(other)); return *this; }
template <int N> List& operator =(T(&other)[N]) { clear(); insert(begin(), std::begin(other), std::end(other)); return *this;}
void assign(const size_t count, const T& value) { clear(); insert(begin(), count, value); }
void assign(const std::initializer_list<T>& il) { clear(); insert(begin(), il.begin(), il.end()); }
template <typename Iter> void assign(const Iter& first, const Iter& last) { clear(); insert(begin(), first, last);}
template <int N> void assign(const T(&other)[N]) { clear(); insert(begin(), std::begin(other), std::end(other)); return *this; }
template <int N> void assign(T(&other)[N]) { clear(); insert(begin(), std::begin(other), std::end(other)); return *this; }
// Destructor ---------------------
~List() { clear(); }
// Element Access -----------------
T& front() { return *begin(); }
T& back() { return *(--end()); }
// Iterators ----------------------
iterator begin() const { return iterator(head->next, head); }
iterator end() const { return iterator(head, head); }
// Capacity -----------------------
size_t size() const { return numberOfElements; }
bool empty() { return size() == 0; }
// Modifiers ----------------------
void clear();
iterator insert(const iterator& insertBeforePosition, const T& value);
iterator insert(const iterator& insertBeforePosition);
template <class Iter, std::enable_if_t<is_iterator<Iter>::value, bool> = true>
iterator insert(const iterator& insertBeforePosition, const Iter& first, const Iter& last);
iterator insert(const iterator& insertBeforePosition, const size_t& count, const T& value);
iterator insert(const iterator& insertBeforePosition, const std::initializer_list<T>& il);
iterator erase(const iterator& posToDelete);
iterator erase(const iterator& first, const iterator& last);
void push_back(const T& d) { insert(end(), d); }
void pop_back() { erase(--end()); };
void push_front(const T& d) { insert(begin(), d); }
void pop_front() { erase(begin()); };
void resize(size_t count);
void resize(size_t count, const T& value);
void swap(List& other) { std::swap(head, other.head); std::swap(numberOfElements, other.numberOfElements); }
// Operations --------------------
void reverse();
// Non standard inefficient functions --------------------------
T& operator[](const size_t index) const { return begin()[index]; }
// ------------------------------------------------------------------------
// Define iterator capability ---------------------------------------------
struct iterator {
// Definitions ----------------
using iterator_category = std::bidirectional_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = T;
using pointer = T*;
using reference = T&;
// Data -----------------------
Node* iter{};
Node* head{};
// Constructor ----------------
iterator(Node*const node, Node* const h) : iter(node), head(h) {};
iterator() {};
// Dereferencing --------------
reference operator*() const { return iter->data; }
reference operator->() const { return &**this; }
// Arithmetic operations ------
iterator operator () { iter = iter->next; return *this; }
iterator operator (int) { iterator tmp = *this; * this; return tmp; }
iterator operator--() { iter = iter->previous; return *this; }
iterator operator--(int) { iterator tmp = *this; --* this; return tmp; }
iterator operator (const difference_type& n) const {
iterator temp{ *this }; difference_type k{ n }; if (k > 0) while (k--) temp; else while (k )--temp; return temp;
}
iterator operator =(const difference_type& n) {
difference_type k{ n }; if (k > 0) while (k--) * this; else while (k )--* this; return *this;
};
iterator operator -(const difference_type& n) const {
iterator temp{ *this }; difference_type k{ n }; if (k > 0) while (k--)--temp; else while (k ) temp; return temp;
}
iterator operator -=(const difference_type& n) {
difference_type k{ n }; if (k > 0) while (k--)--* this; else while (k ) * this; return *this;
};
// Comparison ----------------- (typical space ship implementation)
bool operator ==(const iterator& other) const { return iter == other.iter; };
bool operator !=(const iterator& other) const { return iter != other.iter; };
bool operator < (const iterator& other) const { return other.iter - iter < 0; };
bool operator <= (const iterator& other) const { return other.iter - iter <= 0; };
bool operator > (const iterator& other) const { return other.iter - iter > 0; };
bool operator >= (const iterator& other) const { return other.iter - iter >= 0; };
// Special non standard functions -----------------
difference_type operator-(const iterator& other) const;
reference operator[] (const size_t index);
};
};
// ------------------------------------------------------------------------------------------------
// Implementation of list functions. This would normally go into a TCC file -----------------------
// List class functions ---------------
template <typename T>
void List<T>::clear() {
for (Node* nextNode{}, * currentNode(head->next); currentNode != head; currentNode = nextNode) {
nextNode = currentNode->next;
delete currentNode;
}
init();
}
template <typename T>
typename List<T>::iterator List<T>::insert(const List<T>::iterator& insertBeforePosition, const T& value)
{
Node* nodeInsertBeforePosition = insertBeforePosition.iter;
Node* newNode = new Node(nodeInsertBeforePosition, nodeInsertBeforePosition->previous, value);
nodeInsertBeforePosition->previous = newNode;
(newNode->previous)->next = newNode;
numberOfElements;
return iterator(newNode, head);
}
template <typename T>
typename List<T>::iterator List<T>::insert(const List<T>::iterator& insertBeforePosition)
{
Node* nodeInsertBeforePosition = insertBeforePosition.iter;
Node* newNode = new Node(nodeInsertBeforePosition, nodeInsertBeforePosition->previous);
nodeInsertBeforePosition->previous = newNode;
(newNode->previous)->next = newNode;
numberOfElements;
return iterator(newNode, head);
}
template <typename T>
template <class Iter, std::enable_if_t<is_iterator<Iter>::value, bool>>
typename List<T>::iterator List<T>::insert(const List<T>::iterator& insertBeforePosition, const Iter& first, const Iter& last) {
iterator result(insertBeforePosition.iter, head);
if (first != last) {
result = insert(insertBeforePosition, *first);
Iter i(first);
for ( i; i != last; i)
insert(insertBeforePosition, *i);
}
return result;
}
template <typename T>
typename List<T>::iterator List<T>::insert(const List<T>::iterator& insertBeforePosition, const size_t& count, const T& value) {
iterator result(insertBeforePosition.iter, head);
if (count != 0u) {
result = insert(insertBeforePosition, value);
for (size_t i{ 1u }; i < count; i)
insert(insertBeforePosition, value);
}
return result;
}
template <typename T>
typename List<T>::iterator List<T>::insert(const List<T>::iterator& insertBeforePosition, const std::initializer_list<T>& il) {
return insert(insertBeforePosition, il.begin(), il.end());
}
template <typename T>
typename List<T>::iterator List<T>::erase(const List<T>::iterator& posToDelete) {
iterator result = posToDelete;
result;
Node* nodeToDelete = posToDelete.iter;
if (nodeToDelete != head) {
nodeToDelete->previous->next = nodeToDelete->next;
nodeToDelete->next->previous = nodeToDelete->previous;
delete nodeToDelete;
--numberOfElements;
}
return result;
}
template <typename T>
typename List<T>::iterator List<T>::erase(const List<T>::iterator& first, const List<T>::iterator& last) {
iterator result{ end() };
if (first == begin() && last == end())
clear();
else {
while (first != last)
first = erase(first);
result = last;
}
return result;
}
template <typename T>
void List<T>::resize(size_t count) {
if (numberOfElements < count)
for (size_t i{ numberOfElements }; i < count; i)
insert(end());
else
while (count--)
pop_back();
}
template <typename T>
void List<T>::resize(size_t count, const T& value) {
if (numberOfElements < count)
for (size_t i{ numberOfElements }; i < count; i)
insert(end(),value);
else
while (count--)
pop_back();
}
template <typename T>
void List<T>::reverse() {
const Node* oldHead = head;
for (Node* nptr = head; ; nptr = nptr->previous) {
std::swap(nptr->next, nptr->previous);
if (nptr->previous == oldHead) // Previous was the original next
break;
}
}
// ------------------------------------
// Iterator functions -----------------
template <typename T>
typename List<T>::iterator::difference_type List<T>::iterator::operator-(const iterator& other) const {
difference_type result{};
Node* nptr = head;
int indexThis{ -1 }, indexOther{ -1 }, index{};
do {
nptr = nptr->next;
if (nptr == iter)
indexThis = index;
if (nptr == other.iter)
indexOther = index;
index;
} while (nptr != head);
if (indexThis >= 0 and indexOther >= 0)
result = indexThis - indexOther;
return result;
}
template <typename T>
typename List<T>::iterator::reference List<T>::iterator::operator[] (const size_t index) {
Node* nptr = head->next;
for (size_t i{}; i < index and nptr != head; i, nptr = nptr->next)
;
return nptr->data;
}
// ------------------------------------------------------------------------------------------------
// This would be in a cpp file --------------------------------------------------------------------
int main() {
std::list<int> list1{ 1, 2, 3, 4, 5 };
std::cout << std::distance(list1.end(), list1.begin()) << '\n';
List<int> list3{10,20};
List<int>::iterator l3 = list3.end();
for (int k = 0; k < 10; k) {
std::cout << *l3 << ' ';
--l3;
}
std::cout << '\n';
List<int> list2{ 1, 2, 3, 4, 5 };
for (int i : list2)
std::cout << i << ' '; std::cout << '\n';
std::cout << list2.begin() - list2.end() << '\n';
std::cout << list2.end() - list2.begin() << '\n';
List<int>::iterator i = list2.end();
while (i-- != list2.begin())
std::cout << *i << ' '; std::cout << '\n';
i = list2.end();
int counter = 0;
while (i != list2.end()) {
counter;
i;
}
std::cout << counter << '\n';
std::cout << std::distance(list2.end(), list2.begin()) << '\n';
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/519574.html
標籤:C 数组功能模板链表
上一篇:VanillaJSTyperror:'無法讀取未定義的屬性(讀取'getBoundingClientRect')|為什么?
