#c #sorting
#c #сортировка
Вопрос:
Я пишу код для сортировки вставки для целочисленных данных в связанный список на c , я ссылался на алгоритмы в Интернете и, наконец, взял следующий код, используя array в качестве базовой концепции для моей версии. однако сортировка всегда игнорирует мой первый элемент (но все остальные элементы упорядочены хорошо).
Я попытался проверить свой оператор цикла, проверяя адрес указателя во время цикла (потому что мой цикл с ключевым указателем в первый раз не попал в цикл указателя судьи), проверяя механизм переключения при сравнении, но я не могу найти свою логическую проблему.
(Я знаю, что кто-то сказал бы, что я не предоставляю достаточно данных, чтобы вы могли мне помочь, но я проверял эти вещи в течение двух дней, в том числе спрашивал друзей и искал решения, существующие на веб-сайте. Поэтому я действительно надеюсь, что кто-нибудь сможет ответить мне без вины, спасибо.)
версия массива (в Интернете)
#include <iostream>
void InsertionSort(int *arr, int size){
for (int i = 1; i < size; i ) {
int key = arr[i];
int j = i - 1;
while (key < arr[j] amp;amp; j >= 0) {
arr[j 1] = arr[j];
j--;
}
arr[j 1] = key;
}
}
версия связанного списка (моя собственная)
Класс узла, используемый в моей версии
class Node
{
public:
Node()
{
next = NULL;
pre = NULL;
}
Node(int n)
{
data = n;
next = NULL;
pre = NULL;
}
int getData() { return data; }
Node *getNext() { return next; }
Node *getPre() { return pre; }
void setData(int d) { data = d; }
void setNext(Node *n) { next = n; }
void setPre(Node *p) { pre = p; }
private:
int data;
Node *next, *pre;
};
class List
{
public:
List() { list = NULL; }
List(int n) { generate(n); }
void generate(int n)
{
int j;
list = NULL;
for(j = 0;j < n;j )
generate();
}
void generate()
{
Node *buf = new Node(rand());
buf->setNext(list); //list->NODE2.next->NODE1.next->NULL
if(list != NULL)
list->setPre(buf);
list = buf;
}
void insertionSort()
{
bool breakByCompare;
Node* keyptr;
Node* judgeptr;// judge is the value that is going to compare with key
int key;
for(keyptr = list->getNext(); keyptr != NULL;
keyptr = keyptr->getNext()){
//if we set list as 5,7,6 ; 6 is key
key = keyptr->getData();//store the key value for the setting after shifting
breakByCompare = 0;
for(judgeptr = keyptr->getPre() ; judgeptr->getPre()!= NULL;
judgeptr= judgeptr->getPre()){
//list: 5,7,6 ; 7 is judge
if(judgeptr->getData() > key){
// 7>6, so we shift 7 to the position which was for 6
judgeptr->getNext()->setData(judgeptr->getData());// list: 5,7,7 ;
cout << judgeptr->getData() << " , " << keyptr->getData() << endl;
}
else{
break;
}
}
judgeptr->getNext()->setData(key);// list: 5,6,7
}
}
void print()
{
Node *cur = list;
while(cur != NULL)
{
cout<<cur->getData()<<" ";
cur = cur->getNext();
}
cout<<endl;
}
private:
Node *list;
};
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <ctime>
#define SIZE 100
int main()
{
srand(time(NULL));
List *l = new List(10);
l->print();
l->insertionSort();
l->print();
}
Комментарии:
1. Странный фрагмент кода здесь
List *l = new List(10); l = new List(10);
, почему вы выделяете свой список дважды?2. Я думаю, чтобы помочь здесь, нам нужно увидеть
List
конструктор. Проблема может заключаться в том, как вы настраиваете свой список, а не в том, как вы его сортируете.3. @john, спасибо, я забыл вставить весь класс list, который я отредактировал.
4. @john код является ошибкой, он изначально предназначен для другой функции сортировки, проверяемой для другого значения ~ Я отредактировал, спасибо.
Ответ №1:
Одно из наиболее важных различий между связанным списком и массивом заключается в том, что иногда требуется обрабатывать первый элемент как особый случай.
Вот исправленная версия вашего метода сортировки :
void insertionSort()
{
bool breakByCompare;
Node* keyptr;
Node* judgeptr;
int key;
for(keyptr = list->getNext(); keyptr != NULL; keyptr = keyptr->getNext()){
key = keyptr->getData();
breakByCompare = 0;
// I replaced judgeptr->getPre() by judgeptr in the condition
// to allow the backward loop to go until the root
for(judgeptr = keyptr->getPre() ; judgeptr != NULL; judgeptr= judgeptr->getPre()){
if(judgeptr->getData() > key){
judgeptr->getNext()->setData(judgeptr->getData());
cout << judgeptr->getData() << " , " << key << endl;
}
else break;
}
// Here is the special case : we must support a null judgeptr
// and replace its next element by the list
if (judgeptr) judgeptr->getNext()->setData(key);
else list->setData(key);
}
}
Комментарии:
1. Я отредактировал свой вопрос с дополнительной информацией в классе list. И способ, который я использую, не изменяет положение узла, а только сдвигает данные в узле ~ например, 7,2,8 становится 7,7,8 (сдвиг) становится 2,7,8 (поставить ключ спереди), что означает, что мне не нужно менять указатель списка правильно? потому что мой указатель списка всегда находится в первом узле списка. Извините за недостаток информации раньше.
2. С другой стороны, не могли бы вы более подробно объяснить, как моя сортировка обрабатывает первый элемент списка, который также является указателем списка, как особый случай, поэтому он игнорирует его? это из-за невыполненного условия цикла или какой-либо другой проблемы с адресом, о которой я никогда не думал.
3. Извините, что неправильно вас понял, я отредактировал свой пост, который теперь предлагает исправление.