Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 21.08.2009, 14:38   #1
levandowskiy
Пользователь
 
Регистрация: 18.08.2009
Сообщений: 32
По умолчанию Инвертировать связный список

Доброго времени суток, уважаемые посетители форума)

Я продолжаю изучать связные списки. Хочу поблагодарить пользователя pu4koff за оказанную помощь в написании функции по заполнению списка по порядку (очень вам благодарен). Теперь передо мной стоит новая задача нужно написать функцию, принимающую список чисел и заменяющую порядок узлов обратным.
Я написал некий код. Идея его такова :
Запомнить указатель на последний элемент, как last;
1 Найти указатель на предпоследний элемент списка (назовём его i);
2 Последнему указателю, который равен NULL, присвоить значение указателя i (i->link->link = i);
3 Указателю, на который указывает i (i->link), присвоить значение NULL;
И так повторять пока i не будет равно head.;
И наконец присвоить head значение last (head = last);

Не знаю насколько рациональна эта идея, но код, который я написал по ней не работает:

Код:
#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <cstddef>
using namespace std;

struct INT
{
	int num;
	INT *link;
};

typedef INT* intptr;

void insert (intptr& head, intptr& last, int number);
void input (intptr& head);
void output (intptr head);
void inversion (intptr& head);

int _tmain(int argc, _TCHAR* argv[])
{
	char ans;
	int n;
	do
	{
		intptr head=NULL;
		input(head);
		inversion (head);
		output(head);

		cout<<"Continue: ";
		cin>>ans;
	} while (ans=='y'||ans=='Y');
	return 0;
}

void insert (intptr& head, intptr& last, int number)
{
	intptr temp = new INT;
	temp->num = number;
	if (!head)
	{
		head = temp;
		last = head;
		last->link = NULL;
	}
	else
	{
		last->link = temp;
		last = temp;
		last->link = NULL;
	}
}
void input (intptr& head)
{
	int n;
	cout<<"What numbers you want pop: ";
	cin>>n;
	int next;
	intptr last=NULL;
	for (int i=0; i<n; i++)
	{
		cout<<"Input number #"<<i+1<<" : ";
		cin>>next;
		insert(head,last,next);
	}
}
void output (intptr head)
{
	for (intptr i=head; i!=NULL; i=i->link)
	{
		cout<<i->num<<endl;
	}
}
void inversion (intptr& head)
{
	intptr last, temp, i;
	for (i=head; i!=NULL; i->link)
	{
		if (i->link->link==NULL)
		{
			last = i->link;
			i->link->link = i;
			i->link = NULL;
		}
	}
	do
	{
	for (i=head; i!=NULL; i->link)
	{
		if (i->link->link==NULL)
		{
			i->link->link = i;
			i->link = NULL;
		}
	}
	} while (i!=head);
	temp = head->link;
	head->link->link = head;
	head->link = NULL;
	head = last;

}
Плюс ко всему прикрепляю картинку в виде схемы, показывающую, что есть и что должно быть

Заранее благодарю за помощь)
Вложения
Тип файла: pdf Схема на форум.pdf (11.0 Кб, 16 просмотров)
levandowskiy вне форума Ответить с цитированием
Старый 21.08.2009, 15:06   #2
Sazary
В тени
Старожил
 
Аватар для Sazary
 
Регистрация: 19.12.2008
Сообщений: 5,788
По умолчанию

Можно проще. Достаточно менять связи по ходу движения к концу.
Возьмем три указателя a,b и c.
a указывает на второй элемент.
b - на первый, а c - на третий.
Меняем связь у a, чтобы он указывал на b.
Теперь приравниваем b к a и a к c. Таким образом сместились вправо.
Все это дело продолжается до тех пор, пока c!=NULL.
И в конце ставим делаем head->link=NULL.

Код:
#include <iostream>
#include <cstdlib>
#include <cstddef>
using namespace std;

struct INT
{
	int num;
	INT *link;
};

typedef INT* intptr;

void insert (intptr& head, intptr& last, int number);
void input (intptr& head);
void output (intptr head);
intptr inversion (intptr head);

int main()
{
	char ans;
	int n;
	do
	{
		intptr head=NULL;
		input(head);
		head = inversion (head);
		output(head);

		cout<<"Continue: ";
		cin>>ans;
	} while (ans=='y'||ans=='Y');
	return 0;
}

void insert (intptr& head, intptr& last, int number)
{
	intptr temp = new INT;
	temp->num = number;
	if (!head)
	{
		head = temp;
		last = head;
		last->link = NULL;
	}
	else
	{
		last->link = temp;
		last = temp;
		last->link = NULL;
	}
}

void input (intptr& head)
{
	int n;
	cout<<"What numbers you want pop: ";
	cin>>n;
	int next;
	intptr last=NULL;
	for (int i=0; i<n; i++)
	{
		cout<<"Input number #"<<i+1<<" : ";
		cin>>next;
		insert(head,last,next);
	}
}
void output (intptr head)
{
	for (intptr i=head; i!=NULL; i=i->link)
	{
		cout<<i->num<<endl;
	}
}


intptr inversion (intptr head)
{
intptr a, b, c;
a=head->link;
b=head;
c=head->link->link;
while(c!=NULL)
 {
  a->link=b;
  b=a;
  a=c;
  c=c->link;
 }
a->link=b;
head->link=NULL;
return a;
}
Вполне очевидно, чтобы что-то понять, необходимо книги читать.
Не нужно плодить бессмысленных тем. Вас Поиск избавит от многих проблем.

___________________________________ ___________________________________ _______
[=Правила форума=]_____[Поиск]_____[Литература по С++]____[Литература. Паскаль]
Sazary вне форума Ответить с цитированием
Старый 21.08.2009, 15:20   #3
levandowskiy
Пользователь
 
Регистрация: 18.08.2009
Сообщений: 32
По умолчанию

Спасибо, Sazary)
levandowskiy вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как заполнить связный список? levandowskiy Общие вопросы C/C++ 1 18.08.2009 09:00
C++. Односвязный список. Уничтожить список Olya90 Помощь студентам 2 10.06.2009 18:52
Инвертировать стэк в C++ Drozvd Помощь студентам 0 09.04.2009 03:58
Инвертировать таблицу? Ash БД в Delphi 2 29.01.2009 02:23
Данные-проверка-список (список на другом листе) Inbox Microsoft Office Excel 7 26.12.2008 01:43