C++ 是否在链表中按顺序插入节点?
我正在尝试编写一个成员函数,C++ 是否在链表中按顺序插入节点?,c++,linked-list,C++,Linked List,我正在尝试编写一个成员函数,Link*add\u ordered(Link*n),它以字典顺序在列表中添加一个节点,但是,当我尝试打印有序列表时,只打印最后添加的节点,即“Poseidon” 以下是我的节点界面的外观: struct God { // public members of God std::string name; std::string mythology; std::string vehicle; std::string weapon;
Link*add\u ordered(Link*n)
,它以字典顺序在列表中添加一个节点,但是,当我尝试打印有序列表时,只打印最后添加的节点,即“Poseidon”
以下是我的节点界面的外观:
struct God {
// public members of God
std::string name;
std::string mythology;
std::string vehicle;
std::string weapon;
// constructor
God (std::string n, std::string m, std::string v = " ", std::string w = " ")
: name(n), mythology(m), vehicle(v), weapon(w) { }
};
//------------------------------------------------------------------------
class Link {
public:
God god;
// consructor
Link (God g, Link* p = 0, Link* s = 0)
: god(g), prev(p), succ(s) { }
// modifying member functions
Link* insert (Link* n);
Link* add (Link* n);
Link* add_ordered (Link* n);
Link* erase (void);
Link* find (const std::string& v);
// non - modifying member functions
Link* advance (int n);
const Link* find (const std::string& n) const;
Link* previous () { return prev; }
Link* next () { return succ; }
private:
Link* prev;
Link* succ;
};
add_ordered()
中使用的成员函数:
最后,以下是执行节点排序的函数:
Link* Link::add_ordered (Link* n) {
// check if nodes valid
if (n == 0) return this;
if (this == 0) return n;
// pointer to this object
Link *p = this;
// order in lexicographically increasing order in terms of link's god's name
while (p) {
// if new node value smaller than the one in current node, insert before current node.
if (n->god.name < p->god.name){
insert(n);
break;
// otherwise go to previous node in the list
} else {
p = prev;
}
}
// return the newly added, ordered Link
return n;
}
Link*Link::添加订单(Link*n){
//检查节点是否有效
如果(n==0),则返回该值;
如果(this==0)返回n;
//指向此对象的指针
Link*p=这个;
//按字母顺序按链接的神的名字递增
while(p){
//如果新节点值小于当前节点中的值,请在当前节点之前插入。
如果(n->god.namegod.name){
插入(n);
打破
//否则,转到列表中的上一个节点
}否则{
p=上一个;
}
}
//返回新添加的有序链接
返回n;
}
以下是我如何尝试创建有序的双链接列表:
int main () {
// God(name(n), mythology(m), vehicle(v), weapon(w))
// Greek mythology list of Gods
Link* greek_gods = new Link(God("Zeus", "Greek", "", "lightning"));
greek_gods = greek_gods->add_ordered(new Link(God("Hera", "Greek" )));
greek_gods = greek_gods->add_ordered(new Link(God("Athena", "Greek")));
greek_gods = greek_gods->add_ordered(new Link(God("Ares", "Greek")));
greek_gods = greek_gods->add_ordered(new Link(God("Poseidon", "Greek" )));
// print the list
std::cout <<"{";
while (greek_gods) {
std::cout << greek_gods->god.name <<", "
<< greek_gods->god.mythology <<", "
<< greek_gods->god.vehicle <<", "
<< greek_gods->god.weapon;
// I've tried both directions, using greek_gods->next()
if (greek_gods = greek_gods->previous()) std::cout <<'\n';
}
std::cout <<"}";
}
int main(){
//神(名字(n)、神话(m)、交通工具(v)、武器(w))
//希腊神话中的众神名单
Link*希腊神=新链接(神(“宙斯”、“希腊”、“闪电”);
希腊众神=希腊众神->添加(新链接(神(“赫拉”,“希腊”));
希腊众神=希腊众神->添加(新链接(神(“雅典娜”,“希腊”));
希腊众神=希腊众神->添加(新链接(神(“战神”,“希腊”));
希腊神=希腊神->添加(新链接(神(“波塞冬”,“希腊”));
//打印列表
std::coutLink::add_ordered
始终返回其参数(或者this
如果参数为空,则不会在您的案例中执行该分支)
greek_gods = greek_gods->add_ordered(new Link(God("Hera", "Greek" )));
程序中的行将不断使希腊神指向插入的链接。根据@Frerich Raabe的注释,函数add_ordered()
已修改,因此始终返回列表的起始节点。此外,添加了新的条件语句,if
,以检查新节点是否已按顺序排列,如果已按顺序排列,则将其添加到列表前面:
Link* Link::add_ordered (Link* n) {
// check if nodes valid
if (n == 0) return this;
if (this == 0) return n;
// pointer to this object
Link *p = this;
// if node already in order, add it in front of the list
if (n->god.name < p->god.name) {
add(n);
// return current first node of the list
return n;
}
// traverse existing list till new node's name smaller than current node's
while (!(n->god.name < p->god.name) && p) {
// previous node
Link* temp = p;
// if last node's name is smaller than new node's, add new at the end
if (!(p = p->prev)) {
n->prev = nullptr;
n->succ= temp;
temp->prev = n;
return this;
}
}
// add n in front of current node
n->succ = p->succ;
n->prev = p;
if (p->succ){
p->succ->prev = n;
}
p->succ = n;
// return current first node
return this;
}
Link*Link::添加订单(Link*n){
//检查节点是否有效
如果(n==0),则返回该值;
如果(this==0)返回n;
//指向此对象的指针
Link*p=这个;
//如果节点已排序,请将其添加到列表前面
如果(n->god.namegod.name){
添加(n);
//返回列表的当前第一个节点
返回n;
}
//遍历现有列表,直到新节点的名称小于当前节点的名称
而(!(n->god.namegod.name)和&p){
//上一节点
链路*温度=p;
//如果最后一个节点的名称小于新节点的名称,请在末尾添加新节点
如果(!(p=p->prev)){
n->prev=nullptr;
n->succ=温度;
温度->上一个=n;
归还这个;
}
}
//在当前节点前面添加n
n->succ=p->succ;
n->prev=p;
如果(p->succ){
p->succ->prev=n;
}
p->succ=n;
//返回当前第一个节点
归还这个;
}
我应该“倒带”吗希腊众神
在使用它打印列表之前指向一个结束链接?我的想法是,似乎只有最后一个节点存在,与任何其他节点分离…我是否应该在列表的开头指向希腊众神
在每次将节点插入正确位置后?它是否应该是无效添加顺序()?
我不知道(但我的猜测是:不,add_ordered
不应返回void
)。您需要确定返回值指示的内容。我的印象是您希望它成为列表的新开始。例如,在调用a=b->add_ordered(c);
中,a
的值将是b
(如果添加的链接c
大于b
),或者它将是c
(如果添加的链接小于b
)…因此,add\u ordered
应返回*this;
或返回n;
。如果给定链接大于*this
,则前者应发生。如果给定链接小于*this
(即,它成为列表的新标题),则后者应发生。
Link* Link::add_ordered (Link* n) {
// check if nodes valid
if (n == 0) return this;
if (this == 0) return n;
// pointer to this object
Link *p = this;
// if node already in order, add it in front of the list
if (n->god.name < p->god.name) {
add(n);
// return current first node of the list
return n;
}
// traverse existing list till new node's name smaller than current node's
while (!(n->god.name < p->god.name) && p) {
// previous node
Link* temp = p;
// if last node's name is smaller than new node's, add new at the end
if (!(p = p->prev)) {
n->prev = nullptr;
n->succ= temp;
temp->prev = n;
return this;
}
}
// add n in front of current node
n->succ = p->succ;
n->prev = p;
if (p->succ){
p->succ->prev = n;
}
p->succ = n;
// return current first node
return this;
}