Помощь - Поиск - Пользователи - Календарь
Полная версия: Си задача на упорядоченный список
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Ада и другие языки
Eichhorn
Из командной строки программе подается имя файла, содержащего слова (длины слов ограничены некой константой).
Программа считывает слова, и по очереди добавляет их в упорядоченный список, сохраняя упорядоченность списка на каждом шаге.
После считывания всех строк, программа выводит список на экран - сперва в прямом, затем в обратном порядке.

Для вывода списка в обратном порядке, список необходимо развернуть (сделать так, чтобы последний элемент стал первым, и т. д.).
Реализацию разворота списка выполнить двумя способами: итеративно (”в цикле”) и рекурсивно. Продемонстрировать работу обоих способов.

Пример:
input.txt:
cccc z bbb

program.exe input.txt
bbb cccc z
z cccc bbb


Код

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>

#define N 10

struct list{
    char data;
    struct list*next;
};

struct list * create(int data) {

    struct list *p = (struct list*)calloc(1,sizeof(struct list));
    p->data=data;
    p->next=0;
    return p;        
}

struct list * insert_sorted(struct list * head, int data) {
    struct list *i=head;
    struct list *k=head->next;

    //1. создать элемент списка с пом. create
    struct list *p=create(data);        

    //2. проверить, нужно ли вставить новый элемент перед головой
    //3. если да, сделать так и вернуть указатель на этот элемент (новая голова)
    if(data<head->data){
        p->next=head;
        return p;
    }

    //4. если нет, написать цикл, подыскивающий место для вставки нового элемента
    //5. вставить элемент в найденную позицию
    while(k!=0 && k->data<data){
        k=k->next;
        i=i->next;
    }

    i->next=p;
    p->next=k;
    

    //6. вернуть "старую" голову (не потерять ее)
    return head;
}

void print_list(struct list * head) {
    struct list * p = head;
    while(p!=0){
        printf("%d ", p->data);
        p=p->next;
    }
}

struct list * reverse_list(struct list * head) {

    struct list * p = head;
    struct list * s = head->next;
    struct list * t = s->next;
    p->next=NULL;
    while(s->next) {
        s->next = p;
        p = s;
        s = t;
        t = t->next;
    }
    s->next = p;
    head = s;
    p = head;
    while(p->next){

        printf("%d ",p->data);
        p = p->next;
    }
    printf("%d ",p->data);
}

void free_list(struct list * head) {
    struct list * p=head;
    while(p!=0){
        free(p);
        p=p->next;
    }
}

int main() {
        int n;
    struct list * p =0;
    //1. Завести переменную-указатель на голову списка (head).
    struct list * head=0;
    //2. Корректно открыть файл и т. д.
    FILE * f=fopen("fail.txt","r");

    if(f==0){
        printf("%s","Fail ne otkrit\n");
    //    return -1;
    }
    //3. Считать из файла первый элемент (число)
    /*fscanf(f,"%d",&n);
    //4. создать с этим число новый элемент списка, записать его в head.
    head = create(n);
    //5. написать цикл "пока есть что читать из файла"
    while(!feof(f)){
        //6. в цикле - читать очередной элемент данных
        fscanf(f,"%d",&n);
        //7. добавлять элемент в список с помощью функции insert_sorted
        head = insert_sorted(head,n);
    }
    //8. после цикла - вывести на экран список
    print_list(head);
    //9. развернуть список
    reverse_list(head);
    //10. вывести еще раз список
    print_list(head);
    //11. освободить список
    free_list(head);
    fclose(f); */
    getch();
    return 0;
}


Не могу найти ошибку. Пишу в devcpp. Вылетает с непонятной ошибкой.
IUnknown
Что именно вылетает? У тебя ж всё закомментировано, ничего не выполняется. Открывается файл и всё. А если имеется в виду раскомментированный код - то естественно, что программа вылетает. Смотри:

struct list{
char data; /* Запоминай: данные - типа char !!! */
struct list *next;
};

, что происходит потом? Ты пытаешься
struct list * create(int data)
{
struct list *p = (struct list*)calloc(1, sizeof(struct list));
p->data = data; /* <--- Занести в этот самый char значение из int. Уже ошибка */
p->next = 0;
return p;
}
. Ну, и наконец... Читать из файла надо слова, а это вообще char*, а не числа, и тем более не char-ы.


P.S. Еще кое-что.

У тебя функция reverse_list() предназначена для чего? Чтоб развернуть список. Не должна она ничего печатать. Достаточно вернуть указатель на новую "голову" списка, и потом распечатать через print_list() :

struct list * reverse_list(struct list * head)
{
struct list * p = head;
struct list * s = head->next;
struct list * t = s->next;

p->next=NULL;
while(s->next) {
s->next = p;
p = s;
s = t;
t = t->next;
}
s->next = p;
return s; /* Вот этого не было, хотя компилятор предупреждает !!! */
}

/* В основной программе: */

/* 8. После цикла - вывести на экран список */
print_list(head);

/* 9. Развернуть список */
head = reverse_list(head);

/* 10. Вывести еще раз список, уже "перевернутый" */
print_list(head);

Eichhorn
Мм. Сори, не уточнила. Нам сказали сначала сделать с числами. Отсюда и путаница с типами данных. Там должно быть Int. Не заметила, что не везде исправила. Спасибо за подсказку. Сейчас исправлю, перепроверю.
А закомментировано потому что я искала где вылетает и забыла снять комментарий, когда сюда код копировала.

Добавлено через 5 мин.
Спасибо огромное!!! Всё работает! good.gif smile.gif
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.