C++将LinkedList拆分为2并销毁输入List
C++ Split a LinkedList into 2 and destroy input List
来自C++初学者。我写了一个方法(如下),将输入列表拆分为另外两个列表,并保持原始列表不变(它有效),我需要一个新的方法"拆分"来破坏输入链*this并使用其节点来构建链a和b。我删除原始链的尝试未成功。提前谢谢。
// Split A into two chains B and C.
// When done, A is unchanged.
template <class T>
void chain<T>split(chain<T>& A, chain<T>& B, chain<T>& C)
{
// first free all nodes in B and C
int j;
j=0 ;
listSize = B.listSize;
for (j=0 ; j < listSize; j++)
B.erase(0);
// C.Erase();
j=0 ;
listSize = C.listSize;
for (j=0 ; j < listSize; j++)
C.erase(0);
// assign elements alternately to B and C
int n=0;
chain<T>::iterator a = A.begin(); // find first node of A
while (a != A.end()) {
// first give B an element
B.insert(n,*a);
a++;
if (a == A.end()) break;
// now give C an element
C.insert(n,*a);
a++;
n=n+1;
}
}
#ifndef chain_
#define chain_
#include "linearList.h"
#include "chainNode.h"
using namespace std;
template<class T>
class linkedDigraph;
template <class T> class linkedWDigraph;
template<class T>
class chain : public linearList<T>
{
friend linkedDigraph;
friend linkedWDigraph<int>;
friend linkedWDigraph<float>;
friend linkedWDigraph<double>;
public:
// constructor, copy constructor and destructor
chain(int initialCapacity = 10);
chain(const chain<T>&);
~chain();
// ADT methods
bool empty() const {return listSize == 0;}
int size() const {return listSize;}
T& get(int theIndex) const;
int indexOf(const T& theElement) const;
void erase(int theIndex);
void Split(chain<T>& A, chain<T>& B, chain<T>& C);
//Operator []
typedef int size_type;
// iterators to start and end of list
class iterator;
iterator begin() {return iterator(firstNode);}
iterator end() {return iterator(NULL);}
// iterator for chain
class iterator
{
public:
// typedefs required by C++ for a forward iterator
typedef forward_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef T& reference;
// constructor
iterator(chainNode<T>* theNode = NULL)
{node = theNode;}
// dereferencing operators
T& operator*() const {return node->element;}
T* operator->() const {return &node->element;}
// increment
iterator& operator++() // preincrement
{node = node->next; return *this;}
iterator operator++(int) // postincrement
{iterator old = *this;
node = node->next;
return old;
}
// equality testing
bool operator!=(const iterator right) const
{return node != right.node;}
bool operator==(const iterator right) const
{return node == right.node;}
protected:
chainNode<T>* node;
}; // end of iterator class
//Overload []
T& operator[](size_type index)
{
return element[index];
}
const T& operator[](size_type index) const
{
return element[index];
}
protected:
void checkIndex(int theIndex) const;
// throw illegalIndex if theIndex invalid
chainNode<T>* firstNode; // pointer to first node in chain
int listSize; // number of elements in list
};
template<class T>
chain<T>::chain(int initialCapacity)
{// Constructor.
if (initialCapacity < 1)
{ostringstream s;
s << "Initial capacity = " << initialCapacity << " Must be > 0";
throw illegalParameterValue(s.str());
}
firstNode = NULL;
listSize = 0;
}
template<class T>
chain<T>::chain(const chain<T>& theList)
{// Copy constructor.
listSize = theList.listSize;
if (listSize == 0)
{// theList is empty
firstNode = NULL;
return;
}
// non-empty list
chainNode<T>* sourceNode = theList.firstNode;
// node in theList to copy from
firstNode = new chainNode<T>(sourceNode->element);
// copy first element of theList
sourceNode = sourceNode->next;
chainNode<T>* targetNode = firstNode;
// current last node in *this
while (sourceNode != NULL)
{// copy remaining elements
targetNode->next = new chainNode<T>(sourceNode->element);
targetNode = targetNode->next;
sourceNode = sourceNode->next;
}
targetNode->next = NULL; // end the chain
}
template<class T>
chain<T>::~chain()
{// Chain destructor. Delete all nodes in chain.
while (firstNode != NULL)
{// delete firstNode
chainNode<T>* nextNode = firstNode->next;
delete firstNode;
firstNode = nextNode;
}
}
template<class T>
void chain<T>::checkIndex(int theIndex) const
{// Verify that theIndex is between 0 and listSize - 1.
if (theIndex < 0 || theIndex >= listSize)
{ostringstream s;
s << "index = " << theIndex << " size = " << listSize;
throw illegalIndex(s.str());
}
}
template<class T>
T& chain<T>::get(int theIndex) const
{// Return element whose index is theIndex.
// Throw illegalIndex exception if no such element.
checkIndex(theIndex);
// move to desired node
chainNode<T>* currentNode = firstNode;
for (int i = 0; i < theIndex; i++)
currentNode = currentNode->next;
return currentNode->element;
}
template<class T>
int chain<T>::indexOf(const T& theElement) const
{// Return index of first occurrence of theElement.
// Return -1 if theElement not in list.
// search the chain for theElement
chainNode<T>* currentNode = firstNode;
int index = 0; // index of currentNode
while (currentNode != NULL &&
currentNode->element != theElement)
{
// move to next node
currentNode = currentNode->next;
index++;
}
// make sure we found matching element
if (currentNode == NULL)
return -1;
else
return index;
}
template<class T>
void chain<T>::erase(int theIndex)
{// Delete the element whose index is theIndex.
// Throw illegalIndex exception if no such element.
checkIndex(theIndex);
// valid index, locate node with element to delete
chainNode<T>* deleteNode;
if (theIndex == 0)
{// remove first node from chain
deleteNode = firstNode;
firstNode = firstNode->next;
}
else
{ // use p to get to predecessor of desired node
chainNode<T>* p = firstNode;
for (int i = 0; i < theIndex - 1; i++)
p = p->next;
deleteNode = p->next;
p->next = p->next->next; // remove deleteNode from chain
}
listSize--;
delete deleteNode;
}
template<class T>
void chain<T>::insert(int theIndex, const T& theElement)
{// Insert theElement so that its index is theIndex.
if (theIndex < 0 || theIndex > listSize)
{// invalid index
ostringstream s;
s << "index = " << theIndex << " size = " << listSize;
throw illegalIndex(s.str());
}
if (theIndex == 0)
// insert at front
firstNode = new chainNode<T>(theElement, firstNode);
else
{ // find predecessor of new element
chainNode<T>* p = firstNode;
for (int i = 0; i < theIndex - 1; i++)
p = p->next;
// insert after p
p->next = new chainNode<T>(theElement, p->next);
}
listSize++;
}
template <class T>
void chain<T>::Split(chain<T>& A, chain<T>& B, chain<T>& C)
{// Split A into two chains B and C.
// When done, A is unchanged.
// first free all nodes in B and C
// find firt node of A
// B.erase();
int j;
j=0 ;
listSize = B.listSize;
for (j=0 ; j < listSize; j++)
B.erase(0);
// C.Erase();
j=0 ;
listSize = C.listSize;
for (j=0 ; j < listSize; j++)
C.erase(0);
for (chain<T>::iterator b = A.begin();
b != A.end(); b++)
cout << "A from in " << *b << " ";
// assign elements alternately to B and C
int n=0;
chain<T>::iterator a = A.begin();
chainNode<T> *current;
while (a != A.end()) {
B.insert(n,*a);// first give B an element
a++;
if (a == A.end()) break;
C.insert(n,*a); // now give C an element
a++;
n=n+1;
}
}
// chain node
#ifndef chainNode_
#define chainNode_
template <class T>
struct chainNode
{
// data members
T element;//data
chainNode<T> *next;//link
// methods
chainNode() {}
chainNode(const T& element)
{this->element = element;}
chainNode(const T& element, chainNode<T>* next)
{this->element = element;
this->next = next;}
};
#endif
您不能从这里删除原始链。它作为引用传递,这意味着它将存在于整个函数体中。(你可以更强硬地清空它,就像你对B和C所做的那样)。
在C++中,为了能够销毁一个对象,您必须首先确保该对象已被动态分配(即使用new
)。然后,您需要指向该对象的指针,而不是引用。
所以你需要这样改变你的功能:
template <class T>
void chain<T>split(chain<T>* A, chain<T>& B, chain<T>& C)
{
.... // same as before
delete A;
}
注1:我撒谎了,你可以从引用(即delete &A
)中获取指针,但这是一种非常糟糕的做法。
注2:你可以改进的几个小东西:
- 将
end()
存储在某个地方(chain<T>::iterator end = A.end()
)以避免每次计算它 C.listsize
可能应该是一个函数,如果它不是函数,就不要将其值存储在变量中n = n+1
应为++n;
- 不要重复使用相同的循环变量(
for (int j = 0; ...
) - 如果编译器足够新,请使用for each循环(
for (T& t: A)
)和auto
- 您应该向
chain
添加一个empty
方法来对代码进行因子化
相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 2D数组来自文本输入,中间有空格
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 检查输入是否不是整数或数字
- 正在尝试了解输入验证循环
- 读取文件并输入到矢量中
- C++如何通过用户输入删除列表元素
- 用c++从输入文件中读取另一行
- 读取文件的最后一行并输入到链接列表时出错
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 如何使用用户输入在C++中正确填充2D数组
- C++MySQL C api用户输入行
- 如何在 C 中正确使用 libiconv 使其不会报告"Arg list too long"?
- C++中带有List类的迭代器Segfault
- 使用"std::unordereded_map"映射到"std::list"对象
- 输入到文件并输出到另一个文件,并将流文件传递给函数
- C++将LinkedList拆分为2并销毁输入List
- C++中的Merge Sort Singly Linked List在大输入时失败