我正在学习课堂上的双重链接列表,我被分配编写一个程序,从文件中获取输入,创建双向链表,对其进行排序并输出到屏幕。我观察到奇怪的行为,我无法弄清楚原因。
在数据文件中,当我输入一个长度超过1位的数字时,它会消失。但是,如果我的所有输入都是单个数字,则程序运行正常并按预期进行排序。我意识到他们可能是其他错误,我会稍后再说出来。我只需要知道为什么它会删除两位数输入。
当我的integer.dat文件看起来像“6 4 2 8 4 9 0 4”时,我的程序有效。但是当我的integer.dat文件的数字大于9时,它会“推出”。
这是我的代码。
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
struct Node1
{
int item = 9;
Node1 * prev = NULL;
Node1 * next = NULL;
};
Node1 * findlastnode (Node1 *base)
{
while (base->next != NULL)
{
base = base->next;
}
return base;
}
Node1 * findFirstNode(Node1 * base)
{
Node1 * nodefirst = base;
while (nodefirst->prev != NULL)
{
nodefirst = nodefirst->prev;
}
return nodefirst;
}
int countNodes(Node1 * base)
{
int counter = 0;
Node1 * first = findFirstNode(base);
while (first->next != NULL)
{
counter++;
first = first->next;
}
return counter;
}
void swapItem(Node1 * a1, Node1 * a2)
{
int temp;
temp = a1->item;
a1->item = a2->item;
a2->item = temp;
}
Node1 * deleteLastNode(Node1 * a1)
{
a1 = a1->prev;
Node1 * temp = a1->next;
delete temp;
return a1;
}
void print(Node1 * head)
{
Node1 * tempo = head;
while (tempo->next != NULL)
{
cout << tempo->item << " ";
tempo = tempo->next;
}
}
void printDescending(Node1 * head)
{
Node1 * end = findlastnode(head);
while (end->prev != NULL)
{
cout << end->item << " ";
end = end->prev;
}
}
void printEvenAscending(Node1 * head)
{
Node1 * tempo = head;
while (tempo->next != NULL)
{
if (tempo->item % 2 == 0)
{
cout << tempo->item << " ";
tempo = tempo->next;
}
}
}
void printEvenDescending(Node1 * head)
{
Node1 * end = findlastnode(head);
while (end->prev != NULL)
{
if (end->item % 2 == 0)
{
cout << end->next << " ";
end = end->prev;
}
}
}
Node1 * createList(ifstream & intfile)
{
Node1 * headNode = new Node1;
Node1 * tempNode = new Node1;
headNode->next = tempNode;
tempNode->prev = headNode;
intfile >> headNode->item;
int counter = 1;
while (!intfile.eof())
{
intfile >> tempNode->item;
Node1 * newNode = new Node1;
tempNode->next = newNode;
newNode->prev = tempNode;
tempNode = newNode;
counter++;
}
tempNode->next = NULL;
return headNode;
}
void sortMyList(Node1 * inputList)
{
bool isSorted = false;
Node1 * headNode = inputList;
Node1 * iterator = headNode;
while (!isSorted)
{
if (iterator->next == NULL) break;
if ( (iterator->item > iterator->next->item) && !isSorted)
{
if (iterator->next != NULL)
{
swapItem(iterator, iterator->next);
}
iterator = headNode;
}
if ( iterator->next->item >= iterator->item )
{
iterator = iterator->next;
}
}
}
void addToList(Node1 * head, int xyz)
{
Node1 * lastNode = findlastnode(head);
Node1 * newNode = new Node1;
lastNode->next = newNode;
newNode->prev = lastNode;
newNode->item = xyz;
cout << "New List will sort." << endl;
sortMyList(head);
}
void removeFromList(Node1 * head,int xyz1)
{
Node1 * someNode = head;
Node1 * tempNode;
Node1 * tempNode1;
bool notremoved = true;
while (notremoved)
{
if (someNode->item == xyz1)
{
//Case if first node
if (someNode->prev == NULL)
{
someNode = someNode->next;
delete someNode->prev;
someNode->prev = NULL;
notremoved = false;
}
//case if the last node
if (someNode->next == NULL)
{
someNode = someNode->prev;
delete someNode->next;
someNode->next = NULL;
notremoved = false;
}
//Case if some node in the middle
if (someNode->next != NULL && someNode->prev != NULL)
{
tempNode = someNode->prev;
tempNode1 = tempNode;
tempNode->next = someNode->next;
tempNode = someNode->next;
tempNode->prev = tempNode1;
delete someNode;
notremoved = false;
}
someNode = someNode->next;
}
}
}
int main()
{
cout << "Lab 6" << endl << endl;
ifstream intfile;
string inputfilename1;
cout << "Would you like to use the built-in integer.dat? (y/n)" << endl;
char answer;
cin >> answer;
if (answer == 'n')
{
cout << endl << "Ok. Where is integer.dat? " << endl;
cin >> inputfilename1;
cout << endl;
intfile.open(inputfilename1.c_str());
}
else if (answer == 'y')
{
intfile.open("integer.dat");
}
if (!intfile)
{ cout << "Error: File cannot be opened" << endl << "Please input a valid file location: ";
string inputfilename;
cin >> inputfilename;
intfile.open(inputfilename.c_str()); }
if (intfile.peek() == std::ifstream::traits_type::eof())
{ cout << "Error: Empty File." << endl << "Please input file name: ";
string inputfilename1;
cin >> inputfilename1;
intfile.open(inputfilename1.c_str()); }
Node1 * myList = createList(intfile);
cout << "List before sort : " << endl;
print(myList);
cout << endl;
cout << "List after sort : " << endl;
sortMyList(myList);
print(myList);
bool runagain = true;
while (runagain)
{
cout << endl << "What would you like to do ? " << endl << endl;
cout << "A) Print out sorted list Ascending" << endl;
cout << "B) Print out sorted list Descending" << endl;
cout << "C) Print out EVEN sorted list Ascending" << endl;
cout << "D) Print out EVEN sorted list Descending" << endl;
cout << "E) Add Integer to list" << endl;
cout << "F) Remove Integer from list" << endl;
cout << "Type a letter and press enter ( eg. 'c' ): ";
cin >> answer;
if (answer == 'A' || answer == 'a')
{
cout << "List in Ascending order : " << endl;
print(myList);
cout << endl << "Would you like to run the program again? (y/n)" << endl;
cin >> answer;
if (answer == 'n') runagain = false;
}
if (answer == 'B' || answer == 'b')
{
cout << "List in Descending order : " << endl;
printDescending(myList);
cout << endl << "Would you like to run the program again? (y/n)" << endl;
cin >> answer;
if (answer == 'n') runagain = false;
}
if (answer == 'C' || answer == 'c')
{
cout << "List of EVEN Ascending: " << endl;
printEvenAscending(myList);
cout << endl << "Would you like to run the program again? (y/n)" << endl;
cin >> answer;
if (answer == 'n') runagain = false;
}
if (answer == 'd' || answer == 'D')
{
cout << "List of Even Descending: " << endl;
printEvenDescending(myList);
cout << endl << "Would you like to run the program again? (y/n)" << endl;
cin >> answer;
if (answer == 'n') runagain = false;
}
if (answer == 'e' || answer == 'E')
{
cout << "What integer would you like to add?" << endl;
int xyz;
cin >> xyz;
addToList(myList, xyz);
print(myList);
cout << endl << "Would you like to run the program again? (y/n)" << endl;
cin >> answer;
if (answer == 'n') runagain = false;
}
if (answer == 'f' || answer == 'F')
{
cout << "What integer would you like removed?" << endl;
int xyz1;
cin >> xyz1;
removeFromList(myList, xyz1);
print(myList);
cout << endl << "Would you like to run the program again? (y/n)" << endl;
cin >> answer;
if (answer == 'n') runagain = false;
}
}
system("pause");
return 0;
}
编辑:这是更新的代码!感谢大家的帮助!
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
struct Node1
{
int item;
Node1 * prev ;
Node1 * next ;
};
Node1 * findTail (Node1 * node)
{
Node1 * base = node;
while (base->next != NULL)
{
base = base->next;
}
return base;
}
Node1 * findFirstNode(Node1 * base)
{
Node1 * nodefirst = base;
while (nodefirst->prev != NULL)
{
nodefirst = nodefirst->prev;
}
return nodefirst;
}
int countNodes(Node1 * base)
{
int counter = 0;
Node1 * first = findFirstNode(base);
while (first->next != NULL)
{
counter++;
first = first->next;
}
return counter;
}
void swapItem(Node1 * a1, Node1 * a2)
{
int temp;
temp = a1->item;
a1->item = a2->item;
a2->item = temp;
}
Node1 * deleteLastNode(Node1 * a1)
{
a1 = a1->prev;
Node1 * temp = a1->next;
delete temp;
return a1;
}
void print(Node1 * head)
{
Node1 * tempo = head;
//We check to see if tempo isnt null, not temp->next because wed be checking tempo->next twice
while (tempo != NULL)
{
cout << tempo->item << " ";
tempo = tempo->next;
}
}
//CORRECT
void printDescending(Node1 * head)
{
Node1 * end = findTail(head);
cout << end->item << " ";
while (end->prev != NULL)
{
end = end->prev;
cout << end->item << " ";
}
}
//correct
void printEvenAscending(Node1 * node)
{
Node1 * top = node;
if (top->item % 2 == 0)
{
cout << top->item << " ";
}
while (top->next != NULL)
{
top = top->next;
if (top->item % 2 == 0)
{
cout << top->item << " ";
}
}
}
//CORRECT
void printEvenDescending(Node1 * node)
{
Node1 * bottom = findTail(node);
if (bottom->item % 2 == 0)
{
cout << bottom->item << " ";
}
while (bottom->prev != NULL)
{
bottom = bottom->prev;
if (bottom->item % 2 == 0)
{
cout << bottom->item << " ";
}
}
}
//CORRECT
Node1 * createList(ifstream & intfile)
{
Node1 * head;
Node1 * tail;
Node1 * temp;
temp = new Node1;
intfile >> temp->item;
temp->prev = NULL;
head = temp;
tail = temp;
while (intfile.peek() != std::ifstream::traits_type::eof()) //if theres data, do this run
{
temp = new Node1;
intfile >> temp->item;
temp->prev = tail;
tail->next = temp;
tail = temp;
}
tail->next = NULL;
return head;
}
//CORRECT
void sortMyList(Node1 * inputList)
{
bool isSorted = false;
Node1 * headNode = inputList;
Node1 * iterator = headNode;
while (!isSorted)
{
// at the beginning of each iteration we suppose the list is already sorted
isSorted = true;
iterator = headNode;
// till the end of list
while (iterator->next != NULL)
{
if (iterator->next->next != NULL)
{
if ((iterator->item > iterator->next->item))
{
// change elements
swapItem(iterator, iterator->next);
// if change was, so sorting not completed
isSorted = false;
}
}
// go to next item
iterator = iterator->next;
}
}
}
Node1 * addToList(Node1 * head, int xyz)
{
Node1 * node = head;
Node1 * newNode = new Node1;
newNode->item = xyz;
node->prev = newNode;
newNode->next = node;
newNode->prev = NULL;
return newNode;
}
void removeFromList(Node1 * head,int xyz1)
{
Node1 * node = head;
Node1 * nodebefore;
Node1 * nodeafter;
bool notfound = true;
while (notfound)
{
node = node->next;
if (node->item == xyz1)
{
notfound = false;
}
}
nodebefore = node->prev;
nodeafter = node->next;
delete node;
nodebefore->next = nodeafter;
nodeafter->prev = nodebefore;
}
int main()
{
cout << "Lab 6" << endl << endl;
ifstream intfile;
string inputfilename1;
cout << "Would you like to use the built-in integer.dat? (y/n)" << endl;
char answer;
cin >> answer;
if (answer == 'n')
{
cout << endl << "Ok. Where is integer.dat? " << endl;
cin >> inputfilename1;
cout << endl;
intfile.open(inputfilename1.c_str());
}
else if (answer == 'y' || answer == 'Y')
{
intfile.open("integer.dat");
}
if (!intfile)
{ cout << "Error: File cannot be opened" << endl << "Please input a valid file location: ";
string inputfilename;
cin >> inputfilename;
intfile.open(inputfilename.c_str()); }
if (intfile.peek() == std::ifstream::traits_type::eof())
{ cout << "Error: Empty File." << endl << "Please input file name: ";
string inputfilename1;
cin >> inputfilename1;
intfile.open(inputfilename1.c_str()); }
Node1 * myList = createList(intfile);
cout << "List before sort : " << endl;
print(myList);
cout << endl;
/*
cout << "List after sort : " << endl;
sortMyList(myList);
print(myList);
*/
bool runagain = true;
while (runagain)
{
cout << endl << "What would you like to do ? " << endl << endl;
cout << "A) Print out sorted list Ascending" << endl;
cout << "B) Print out sorted list Descending" << endl;
cout << "C) Print out EVEN sorted list Ascending" << endl;
cout << "D) Print out EVEN sorted list Descending" << endl;
cout << "E) Add Integer to list" << endl;
cout << "F) Remove Integer from list" << endl;
cout << "Type a letter and press enter ( eg. 'c' ): ";
cin >> answer;
if (answer == 'A' || answer == 'a')
{
cout << "List in Ascending order : " << endl;
sortMyList(myList);
print(myList);
cout << endl << endl << "Would you like to run the program again? (y/n)" << endl;
cin >> answer;
if (answer == 'n') runagain = false;
}
if (answer == 'B' || answer == 'b')
{
cout << "List in Descending order : " << endl;
sortMyList(myList);
printDescending(myList);
cout << endl << "Would you like to run the program again? (y/n)" << endl;
cin >> answer;
if (answer == 'n') runagain = false;
}
if (answer == 'C' || answer == 'c')
{
cout << "List of EVEN Ascending: " << endl;
sortMyList(myList);
printEvenAscending(myList);
cout << endl << "Would you like to run the program again? (y/n)" << endl;
cin >> answer;
if (answer == 'n') runagain = false;
}
if (answer == 'd' || answer == 'D')
{
cout << "List of Even Descending: " << endl;
sortMyList(myList);
printEvenDescending(myList);
cout << endl << "Would you like to run the program again? (y/n)" << endl;
cin >> answer;
if (answer == 'n') runagain = false;
}
if (answer == 'e' || answer == 'E')
{
cout << "What integer would you like to add?" << endl;
int xyz;
cin >> xyz;
Node1 * newHead = addToList(myList, xyz);
myList = newHead;
print(myList);
cout << endl << "Would you like to run the program again? (y/n)" << endl;
cin >> answer;
if (answer == 'n') runagain = false;
}
if (answer == 'f' || answer == 'F')
{
cout << "Currently does not support removal of first or last element." << endl;
cout << "What integer would you like removed?" << endl;
int xyz1;
cin >> xyz1;
removeFromList(myList, xyz1);
print(myList);
cout << endl << "Would you like to run the program again? (y/n)" << endl;
cin >> answer;
if (answer == 'n') runagain = false;
}
}
system("pause");
return 0;
}<code>
答案 0 :(得分:1)
我认为您的问题是从输入中创建列表的方式。它总是会添加一个比你想要的节点。
另一方面,print()函数过早地停止打印一个节点(它只打印具有后继节点的节点)。
由于您的新节点的默认值为9,如果您只有一位数字,这将始终是最大值,因此您不会在那里看到问题。
答案 1 :(得分:0)
将结构声明更改为
struct Node1
{
int item;
Node1 * prev;
Node1 * next;
};
尝试以下排序功能:
void sortMyList(Node1 * inputList)
{
bool isSorted = false;
Node1 * headNode = inputList;
Node1 * iterator = headNode;
while (!isSorted)
{
// at the beginning of each iteration we suppose the list is already sorted
isSorted = true;
iterator = headNode;
// till the end of list
while (iterator->next != NULL)
{
if( iterator->next->next != NULL )
{
if ( (iterator->item > iterator->next->item) )
{
// change elements
swapItem(iterator, iterator->next);
// if change was, so sorting not completed
isSorted = false;
}
}
// go to next item
iterator = iterator->next;
}
}
}