C ++从具有开始位置和结束位置的列表中删除
C++ Deleting from a List with a start position and a end
如何从列表中删除例如从位置 1 到 4?
我只是用列表中的 1 个元素解决了这个删除问题:
void delPos(int iPos) {
ListElem *pElemToDelete = mpHead;
for (int i = 0; i < iPos; ++i) {
pElemToDelete = pElemToDelete->mpNext;
}
if (pElemToDelete != nullptr) {
if (mpHead == pElemToDelete) {
mpHead = pElemToDelete->mpNext;
delete pElemToDelete;
} else {
for (ListElem *pTmp = mpHead; pTmp != nullptr; pTmp = pTmp->mpNext) {
if (pTmp->mpNext == pElemToDelete) {
pTmp->mpNext = pElemToDelete->mpNext;
delete pElemToDelete;
return;
}
}
}
}
对于位置删除(从头到尾)我得到了这个:
void deleteElem(int start, int end) {
ListElem *pTmp1 = m_pHead;
ListElem *pTmp2 = m_pHead;
for (int i = 0; i < end; ++i) {
if (i < start - 1) {
if (pTmp1->m_pNext != nullptr) {
pTmp1 = pTmp1->m_pNext;
}
}
if (pTmp2->m_pNext != nullptr) {
pTmp2 = pTmp2->m_pNext;
}
}
if (start == 0) {
m_pHead = pTmp2->m_pNext;
} else {
pTmp1->m_pNext = pTmp2->m_pNext;
}
}
但不是真的删了吧?它只是显示指向正确元素的下一个指针。我像上面那样尝试使用 1 个元素,但它不起作用。
也许你们可以给我一些提示?
对于初学者这个函数
void delPos(int iPos) {
ListElem *pElemToDelete = mpHead;
for (int i = 0; i < iPos; ++i) {
pElemToDelete = pElemToDelete->mpNext;
}
//..
当 iPos
大于或等于列表中的节点数时, 可以调用未定义的行为。
功能可以通过以下方式实现
bool delPos( size_t iPos )
{
ListElem **pElemToDelete = &mpHead;
for ( ; pElemToDelete != nullptr && iPos != 0; --iPos )
{
pElemToDelete = &( *pElemToDelete )->mpNext;
}
bool success = pElemToDelete != nullptr;
if ( success )
{
ListElem *tmp = *pElemToDelete;
*pElemToDelete = ( *pElemToDelete )->mpNext;
delete tmp;
}
return success;
}
现在实现第二个功能就不难了。我假设结束位置不在删除节点的范围内。
bool delPos( size_t iStart, size_t iEnd )
{
bool success = iStart < iEnd;
if ( success )
{
ListElem **pElemToDelete = &mpHead;
size_t i = 0;
for ( ; pElemToDelete != nullptr && i != iStart; ++i )
{
pElemToDelete = &( *pElemToDelete )->mpNext;
}
success = pElemToDelete != nullptr;
if ( success )
{
for ( ; pElemToDelete != nullptr && i != iEnd; i++ )
{
ListElem *tmp = *pElemToDelete;
*pElemToDelete = ( *pElemToDelete )->mpNext;
delete tmp;
}
}
}
return success;
}
这是一个演示程序。
#include <iostream>
class List
{
private:
struct ListElem
{
int data;
ListElem *mpNext;
} *mpHead = nullptr;
public:
List() = default;
void pushFront( int );
bool delPos( size_t );
bool delPos( size_t, size_t );
std::ostream & printList( std::ostream & = std::cout ) const;
};
void List::pushFront( int data )
{
mpHead = new ListElem { data, mpHead };
}
bool List::delPos( size_t iPos )
{
ListElem **pElemToDelete = &mpHead;
for ( ; pElemToDelete != nullptr && iPos != 0; --iPos )
{
pElemToDelete = &( *pElemToDelete )->mpNext;
}
bool success = pElemToDelete != nullptr;
if ( success )
{
ListElem *tmp = *pElemToDelete;
*pElemToDelete = ( *pElemToDelete )->mpNext;
delete tmp;
}
return success;
}
bool List::delPos( size_t iStart, size_t iEnd )
{
bool success = iStart < iEnd;
if ( success )
{
ListElem **pElemToDelete = &mpHead;
size_t i = 0;
for ( ; pElemToDelete != nullptr && i != iStart; ++i )
{
pElemToDelete = &( *pElemToDelete )->mpNext;
}
success = pElemToDelete != nullptr;
if ( success )
{
for ( ; pElemToDelete != nullptr && i != iEnd; i++ )
{
ListElem *tmp = *pElemToDelete;
*pElemToDelete = ( *pElemToDelete )->mpNext;
delete tmp;
}
}
}
return success;
}
std::ostream & List::printList( std::ostream &os ) const
{
for ( ListElem *current = mpHead; current != nullptr; current = current->mpNext )
{
os << current->data << ' ';
}
return os << "nullptr";
}
int main()
{
List lst;
const int N = 10;
for ( int i = 0; i < N; i++ ) lst.pushFront( i );
lst.printList() << '\n';
lst.delPos( 0 );
lst.printList() << '\n';
lst.delPos( 8 );
lst.printList() << '\n';
lst.delPos( 3, 5 );
lst.printList() << '\n';
lst.delPos( 0, 6 );
lst.printList() << '\n';
}
它的输出是
9 8 7 6 5 4 3 2 1 0 nullptr
8 7 6 5 4 3 2 1 0 nullptr
8 7 6 5 4 3 2 1 nullptr
8 7 6 3 2 1 nullptr
nullptr
如何从列表中删除例如从位置 1 到 4?
我只是用列表中的 1 个元素解决了这个删除问题:
void delPos(int iPos) {
ListElem *pElemToDelete = mpHead;
for (int i = 0; i < iPos; ++i) {
pElemToDelete = pElemToDelete->mpNext;
}
if (pElemToDelete != nullptr) {
if (mpHead == pElemToDelete) {
mpHead = pElemToDelete->mpNext;
delete pElemToDelete;
} else {
for (ListElem *pTmp = mpHead; pTmp != nullptr; pTmp = pTmp->mpNext) {
if (pTmp->mpNext == pElemToDelete) {
pTmp->mpNext = pElemToDelete->mpNext;
delete pElemToDelete;
return;
}
}
}
}
对于位置删除(从头到尾)我得到了这个:
void deleteElem(int start, int end) {
ListElem *pTmp1 = m_pHead;
ListElem *pTmp2 = m_pHead;
for (int i = 0; i < end; ++i) {
if (i < start - 1) {
if (pTmp1->m_pNext != nullptr) {
pTmp1 = pTmp1->m_pNext;
}
}
if (pTmp2->m_pNext != nullptr) {
pTmp2 = pTmp2->m_pNext;
}
}
if (start == 0) {
m_pHead = pTmp2->m_pNext;
} else {
pTmp1->m_pNext = pTmp2->m_pNext;
}
}
但不是真的删了吧?它只是显示指向正确元素的下一个指针。我像上面那样尝试使用 1 个元素,但它不起作用。
也许你们可以给我一些提示?
对于初学者这个函数
void delPos(int iPos) {
ListElem *pElemToDelete = mpHead;
for (int i = 0; i < iPos; ++i) {
pElemToDelete = pElemToDelete->mpNext;
}
//..
当 iPos
大于或等于列表中的节点数时,可以调用未定义的行为。
功能可以通过以下方式实现
bool delPos( size_t iPos )
{
ListElem **pElemToDelete = &mpHead;
for ( ; pElemToDelete != nullptr && iPos != 0; --iPos )
{
pElemToDelete = &( *pElemToDelete )->mpNext;
}
bool success = pElemToDelete != nullptr;
if ( success )
{
ListElem *tmp = *pElemToDelete;
*pElemToDelete = ( *pElemToDelete )->mpNext;
delete tmp;
}
return success;
}
现在实现第二个功能就不难了。我假设结束位置不在删除节点的范围内。
bool delPos( size_t iStart, size_t iEnd )
{
bool success = iStart < iEnd;
if ( success )
{
ListElem **pElemToDelete = &mpHead;
size_t i = 0;
for ( ; pElemToDelete != nullptr && i != iStart; ++i )
{
pElemToDelete = &( *pElemToDelete )->mpNext;
}
success = pElemToDelete != nullptr;
if ( success )
{
for ( ; pElemToDelete != nullptr && i != iEnd; i++ )
{
ListElem *tmp = *pElemToDelete;
*pElemToDelete = ( *pElemToDelete )->mpNext;
delete tmp;
}
}
}
return success;
}
这是一个演示程序。
#include <iostream>
class List
{
private:
struct ListElem
{
int data;
ListElem *mpNext;
} *mpHead = nullptr;
public:
List() = default;
void pushFront( int );
bool delPos( size_t );
bool delPos( size_t, size_t );
std::ostream & printList( std::ostream & = std::cout ) const;
};
void List::pushFront( int data )
{
mpHead = new ListElem { data, mpHead };
}
bool List::delPos( size_t iPos )
{
ListElem **pElemToDelete = &mpHead;
for ( ; pElemToDelete != nullptr && iPos != 0; --iPos )
{
pElemToDelete = &( *pElemToDelete )->mpNext;
}
bool success = pElemToDelete != nullptr;
if ( success )
{
ListElem *tmp = *pElemToDelete;
*pElemToDelete = ( *pElemToDelete )->mpNext;
delete tmp;
}
return success;
}
bool List::delPos( size_t iStart, size_t iEnd )
{
bool success = iStart < iEnd;
if ( success )
{
ListElem **pElemToDelete = &mpHead;
size_t i = 0;
for ( ; pElemToDelete != nullptr && i != iStart; ++i )
{
pElemToDelete = &( *pElemToDelete )->mpNext;
}
success = pElemToDelete != nullptr;
if ( success )
{
for ( ; pElemToDelete != nullptr && i != iEnd; i++ )
{
ListElem *tmp = *pElemToDelete;
*pElemToDelete = ( *pElemToDelete )->mpNext;
delete tmp;
}
}
}
return success;
}
std::ostream & List::printList( std::ostream &os ) const
{
for ( ListElem *current = mpHead; current != nullptr; current = current->mpNext )
{
os << current->data << ' ';
}
return os << "nullptr";
}
int main()
{
List lst;
const int N = 10;
for ( int i = 0; i < N; i++ ) lst.pushFront( i );
lst.printList() << '\n';
lst.delPos( 0 );
lst.printList() << '\n';
lst.delPos( 8 );
lst.printList() << '\n';
lst.delPos( 3, 5 );
lst.printList() << '\n';
lst.delPos( 0, 6 );
lst.printList() << '\n';
}
它的输出是
9 8 7 6 5 4 3 2 1 0 nullptr
8 7 6 5 4 3 2 1 0 nullptr
8 7 6 5 4 3 2 1 nullptr
8 7 6 3 2 1 nullptr
nullptr