divide()函数(按奇偶拆分链表)错在哪啊?

softwarecai 2011-09-19 10:58:01
// chain.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
using namespace std;

template<class T> class Chain ;
template<class T> class ChainIterator ;
template <class T>
class ChainNode
{
public:
friend ChainIterator<T>;
friend Chain<T>;
T data;
ChainNode<T> *link;
};

template<class T>
class Chain
{
friend ChainIterator<T>;
public:
Chain()
{first = 0;}
ChainNode<T> * Last()
{
ChainNode <T> *cur=first;
while(cur->link)
{
cur=cur->link;
}
return cur;
}
ChainNode<T> * Pre(ChainNode<T> *q)
{
if(q==first)
return 0;
else
{
ChainNode <T> *cur=first;
//ifq==first)
//return 0;
while((cur->link->data)!=(q->data))
{
cur=cur->link;
}
return cur;
}
}
~Chain();

bool IsEmpty() const {return first == 0;}
int Length() const;
bool Find(int k, T& x) const;
int Search(const T& x) const;
Chain<T>& Delete(int k, T& x);
Chain<T>& Insert(int k, const T& x);
void Output(ostream& out) const;
//Chain<T>& merge(Chain<T> &A,Chain<T> &B);
//Chain<T> & divide(Chain<T> &C);
//void print(Chain<T> &C);
//private:
ChainNode <T> *first; // pointer to first node
};
template<class T>
Chain<T>::~Chain()
{// Chain destructor. Delete all nodes in chain.
ChainNode<T> *next; // next node
while (first) {
next = first->link;
delete first;
first = next;
}
}

template<class T>
int Chain<T>::Length() const
{// Return the number of elements in the chain.
ChainNode<T> *current = first;
int len = 0;
while (current) {
len++;
current = current->link;
}
return len;
}

template<class T>
bool Chain<T>::Find(int k, T& x) const
{// Set x to the k'th element in the chain.
// Return false if no k'th; return true otherwise.
if (k < 1) return false;
ChainNode<T> *current = first;
int index = 1; // index of current
while (index < k && current) {
current = current->link;
index++;
}
if (current) {x = current->data;
return true;}
return false; // no k'th element
}

template<class T>
int Chain<T>::Search(const T& x) const
{// Locate x. Return position of x if found.
// Return 0 if x not in the chain.
ChainNode<T> *current = first;
int index = 1; // index of current
while (current && current->data != x) {
current = current->link;
index++;
}
if (current) return index;
return 0;
}

template<class T>
Chain<T>& Chain<T>::Delete(int k, T& x)
{// Set x to the k'th element and delete it.
// Throw OutOfBounds exception if no k'th element.
if (k < 1 || !first)
throw OutOfBounds(); // no k'th

// p will eventually point to k'th node
ChainNode<T> *p = first;

// move p to k'th & remove from chain
if (k == 1) // p already at k'th
first = first->link; // remove
else { // use q to get to k-1'st
ChainNode<T> *q = first;
for (int index = 1; index < k - 1 && q;
index++)
q = q->link;
if (!q || !q->link)
throw OutOfBounds(); // no k'th
p = q->link; // k'th
q->link = p->link;} // remove from chain

// save k'th element and free node p
x = p->data;
delete p;
return *this;
}

template<class T>
Chain<T>& Chain<T>::Insert(int k, const T& x)
{// Insert x after the k'th element.
// Throw OutOfBounds exception if no k'th element.
// Pass NoMem exception if inadequate space.


//modefy by me
//if (k < 0) throw OutOfBounds();

// p will eventually point to k'th node
ChainNode<T> *p = first;
for(int index = 1; index < k && p;
index++) // move p to k'th
p = p->link;
// if (k > 0 && !p) throw OutOfBounds(); // no k'th

// insert
ChainNode<T> *y = new ChainNode<T>;
y->data = x;
if (k) {// insert after p
y->link = p->link;
p->link = y;}
else {// insert as first element
y->link = first;
first = y;}
return *this;
}

template<class T>
void Chain<T>::Output(ostream& out) const
{// Insert the chain elements into the stream out.
ChainNode<T> *current;
for (current = first; current;
current = current->link)
out << current->data << " ";
}

// overload <<
template <class T>
ostream& operator<<(ostream& out, const Chain<T>& x)
{
x.Output(out); return out;
}
template<class T>
Chain<T>& merge(Chain<T> &A,Chain<T> &B)
{
if(!A.first)
return B;
if(!B.first)
return A;
ChainNode<T> *p,*q,*pre;
p=A.first;q=B.first;
int a,b;
//T x;
a=A.Length();
b=B.Length();
if(a<=b)
{
for(;p;p=A.first)
{
while(q&& ((p->data)>(q->data)))
{
q=q->link;
}
if(!q)
{
q=B.Last();
q->link=p;
return B;
}
else
{
A.first=p->link;
//temp=p;
pre=B.Pre(q);
if(pre)
{
//temp->link=q;
p->link=q;
pre->link=p;
}
else
{
p->link=q;
B.first=p;
}
}

}
return B;
}
else if(a>b)
{
for(;q;q=B.first)
{
while(p&& ((p->data)<(q->data)))
{
p=p->link;
}
if(!p)
{
p=A.Last();
p->link=q;
return A;
}
else
{
B.first=q->link;
//temp=p;
pre=A.Pre(p);
if(pre)
{
//temp->link=q;
q->link=p;
pre->link=q;
}
else
{
q->link=p;
A.first=q;
}
}
}
return A;
}
}
template<class T>
void divide(Chain<T> &A,Chain<T> &B,Chain<T> &C)
{
if(C.first==0)
{
A.first=0;
B.first=0;
}
else
{
ChainNode<T> *p,*pa;
ChainNode<T> *pb=0;
p=C.first;
if((p->data)%2)
{
A.first=p;
pa=A.first;

}
else
{
B.first=p;
pb=B.first;
}
p=p->link;
while(p)
{
if((p->data)%2)
{
if (pa==0)
{
A.first=pa;
pa=A.first;
}
else
{
pa->link=p;
}
pa=pa->link;

}
else
{
if(pb==0)
{
B.first=p;
pb=B.first;
}
else
{
pb->link=p;
}
pb=pb->link;

}
p=p->link;
}
/*if((p->data)%2)
{
A.first=p;

}
else
{
B.first=p;
}*/
}
}
template<class T>
class ChainIterator
{
public:
T* Initialize(const Chain<T>& c)
{
location = c.first;
if(location)
return &location->data;
return 0;
}
T* Next( )
{
if (!location) return 0;
location = location->link;
if (location)
return &location->data;
return 0;
}
private:
ChainNode<T> *location;
};int _tmain(int argc, _TCHAR* argv[])
{
Chain<int> L1,L2,L3,L4,L5;
L1.Insert(0,1).Insert(1,3).Insert(2,5);
L2.Insert(0,2).Insert(1,4).Insert(2,8).Insert(3,10);
L3=merge(L1,L2);
ChainIterator<int> C;
int *x1,*x2,*x3;
x1=C.Initialize(L1);
x2=C.Initialize(L2);
x3=C.Initialize(L3);
while(x3)
{
cout<<*x3<<" ";
x3=C.Next();
} cout<<endl;
L2.Output(cout);
cout<<endl;
L1.Output(cout);
cout<<endl;
divide(L4,L5,L3);
L3.Output(cout);
cout<<endl;
L4.Output(cout);
cout<<endl;
L5.Output(cout);
return 0;
}

...全文
96 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
softwarecai 2011-09-21
  • 打赏
  • 举报
回复
断言失败,错在哪里?怎么解决
softwarecai 2011-09-20
  • 打赏
  • 举报
回复
数据结构才学几节课,真的很不习惯用单链表。pre()函数寻找上一个节点,由于升序链表,能保证每个节点的data唯一, 链表中有节点q,Pre(ChainNode<T> *q)只是找前驱(q!=first)故不怕到最后一个节点的时候还没找到。 else
{
pa->link=p;//这里就有问题,你这样直接修改了C链表,C链表原来的节点连接都 被搞乱了
} //你应该记录一下C链表下一个元素的位置
本意是 p=p->link记录一下C链表下一个元素的位置,这样行吗?其实我就是相对c链表遍历,date为奇数的节点放在A链表(安升序),该如何实现呢?
羽飞 2011-09-20
  • 打赏
  • 举报
回复
代码没贴完,不过关键的已经贴了,很明显,楼主拆分链表的逻辑有问题,可以画个图一步一步走走,就很清晰了
羽飞 2011-09-20
  • 打赏
  • 举报
回复

// chain.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
using namespace std;

template<class T> class Chain ;
template<class T> class ChainIterator ;
template <class T>
class ChainNode
{
public:
friend ChainIterator<T>;
friend Chain<T>;
T data;
ChainNode<T> *link;
};

template<class T>
class Chain
{
friend ChainIterator<T>;
public:
Chain()
{first = 0;}
ChainNode<T> * Last()
{
ChainNode <T> *cur=first;
while(cur->link)
{
cur=cur->link;
}
return cur;
}
ChainNode<T> * Pre(ChainNode<T> *q)
{
if(q==first)
return 0;
else
{
ChainNode <T> *cur=first;
//ifq==first)
//return 0;
while((cur->link->data)!=(q->data))//楼主这样查找上一个节点,能保证每个节点的data唯一吗
{ //还有,这样做while循环,不怕到最后一个节点的时候还没找到吗,
//那样的话这个就直接挂掉了
cur=cur->link;
}
return cur;
}
}
~Chain();

bool IsEmpty() const {return first == 0;}
int Length() const;
bool Find(int k, T& x) const;
int Search(const T& x) const;
Chain<T>& Delete(int k, T& x);
Chain<T>& Insert(int k, const T& x);
void Output(ostream& out) const;
//Chain<T>& merge(Chain<T> &A,Chain<T> &B);
//Chain<T> & divide(Chain<T> &C);
//void print(Chain<T> &C);
//private:
ChainNode <T> *first; // pointer to first node
};
template<class T>
Chain<T>::~Chain()
{// Chain destructor. Delete all nodes in chain.
ChainNode<T> *next; // next node
while (first) {
next = first->link;
delete first;
first = next;
}
}

template<class T>
int Chain<T>::Length() const
{// Return the number of elements in the chain.
ChainNode<T> *current = first;
int len = 0;
while (current) {
len++;
current = current->link;
}
return len;
}

template<class T>
bool Chain<T>::Find(int k, T& x) const
{// Set x to the k'th element in the chain.
// Return false if no k'th; return true otherwise.
if (k < 1) return false;
ChainNode<T> *current = first;
int index = 1; // index of current
while (index < k && current) {
current = current->link;
index++;
}
if (current) {x = current->data;
return true;}
return false; // no k'th element
}

template<class T>
int Chain<T>::Search(const T& x) const
{// Locate x. Return position of x if found.
// Return 0 if x not in the chain.
ChainNode<T> *current = first;
int index = 1; // index of current
while (current && current->data != x) {
current = current->link;
index++;
}
if (current) return index;
return 0;
}

template<class T>
Chain<T>& Chain<T>::Delete(int k, T& x)
{// Set x to the k'th element and delete it.
// Throw OutOfBounds exception if no k'th element.
if (k < 1 || !first)
throw OutOfBounds(); // no k'th

// p will eventually point to k'th node
ChainNode<T> *p = first;

// move p to k'th & remove from chain
if (k == 1) // p already at k'th
first = first->link; // remove
else { // use q to get to k-1'st
ChainNode<T> *q = first;
for (int index = 1; index < k - 1 && q;
index++)
q = q->link;
if (!q || !q->link)
throw OutOfBounds(); // no k'th
p = q->link; // k'th
q->link = p->link;} // remove from chain

// save k'th element and free node p
x = p->data;
delete p;
return *this;
}

template<class T>
Chain<T>& Chain<T>::Insert(int k, const T& x)
{// Insert x after the k'th element.
// Throw OutOfBounds exception if no k'th element.
// Pass NoMem exception if inadequate space.


//modefy by me
//if (k < 0) throw OutOfBounds();

// p will eventually point to k'th node
ChainNode<T> *p = first;
for(int index = 1; index < k && p;
index++) // move p to k'th
p = p->link;
// if (k > 0 && !p) throw OutOfBounds(); // no k'th

// insert
ChainNode<T> *y = new ChainNode<T>;
y->data = x;
if (k) {// insert after p
y->link = p->link;
p->link = y;}
else {// insert as first element
y->link = first;
first = y;}
return *this;
}

template<class T>
void Chain<T>::Output(ostream& out) const
{// Insert the chain elements into the stream out.
ChainNode<T> *current;
for (current = first; current;
current = current->link)
out << current->data << " ";
}

// overload <<
template <class T>
ostream& operator<<(ostream& out, const Chain<T>& x)
{
x.Output(out); return out;
}
template<class T>
Chain<T>& merge(Chain<T> &A,Chain<T> &B)
{
if(!A.first)
return B;
if(!B.first)
return A;
ChainNode<T> *p,*q,*pre;
p=A.first;q=B.first;
int a,b;
//T x;
a=A.Length();
b=B.Length();
if(a<=b)
{
for(;p;p=A.first)
{
while(q&& ((p->data)>(q->data)))
{
q=q->link;
}
if(!q)
{
q=B.Last();
q->link=p;
return B;
}
else
{
A.first=p->link;
//temp=p;
pre=B.Pre(q);
if(pre)
{
//temp->link=q;
p->link=q;
pre->link=p;
}
else
{
p->link=q;
B.first=p;
}
}

}
return B;
}
else if(a>b)
{
for(;q;q=B.first)
{
while(p&& ((p->data)<(q->data)))
{
p=p->link;
}
if(!p)
{
p=A.Last();
p->link=q;
return A;
}
else
{
B.first=q->link;
//temp=p;
pre=A.Pre(p);
if(pre)
{
//temp->link=q;
q->link=p;
pre->link=q;
}
else
{
q->link=p;
A.first=q;
}
}
}
return A;
}
}
template<class T>
void divide(Chain<T> &A,Chain<T> &B,Chain<T> &C)
{
if(C.first==0)
{
A.first=0;
B.first=0;
}
else
{
ChainNode<T> *p,*pa;
ChainNode<T> *pb=0;
p=C.first;
if((p->data)%2)
{
A.first=p;
pa=A.first;

}
else
{
B.first=p;
pb=B.first;
}
p=p->link;
while(p)
{
if((p->data)%2)
{
if (pa==0)
{
A.first=pa;
pa=A.first;
}
else
{
pa->link=p;//这里就有问题,你这样直接修改了C链表,C链表原来的节点连接都被搞乱了
} //你应该记录一下C链表下一个元素的位置
pa=pa->link;

}
else
{
if(pb==0)
{
B.first=p;
pb=B.first;
}
else
{
pb->link=p;
}
pb=pb->link;

}
p=p->link; //因为你对pa或pb的操作直接导致这句出现不可预知的错误

64,684

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧