Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
5.9 kB
3
Indexable
Never
#include <stdio.h>
#include <stdlib.h>

// структура односвязного списка
typedef struct Node {
    int value;
    struct Node *next;
} Node;


// добавление нового узла
void push(Node **head, int data) {
    Node *tmp = (Node*) malloc(sizeof(Node));
    tmp->value = data;
    tmp->next = (*head);
    (*head) = tmp;
}

// удаляет элемент, на который указывает head и возвращает его значение
int pop(Node **head) {
    Node* prev = NULL;
    int val;
    if (head == NULL) {
        exit(-1);
    }
    prev = (*head);
    val = prev->value;
    (*head) = (*head)->next;
    free(prev);
    return val;
}

// переход к следующему элементу через указатель next текущего узла

Node* getNth(Node* head, int n) {
    int counter = 0;
    while (counter < n && head) {
        head = head->next;
        counter++;
    }
    return head;
}

// нахождение последнего элемента
Node* getLast(Node *head) {
    if (head == NULL) {
        return NULL;
    }
    while (head->next) {
        head = head->next;
    }
    return head;
}

// вставка элемента в конец списка

void pushBack(Node *head, int value) {
    Node *last = getLast(head);
    Node *tmp = (Node*) malloc(sizeof(Node));
    tmp->value = value;
    tmp->next = NULL;
    last->next = tmp;
}

// возврат указателя на предпоследний элемент

Node* getLastButOne(Node* head) {
    if (head == NULL) {
        exit(-2);
    }
    if (head->next == NULL) {
        return NULL;
    }
    while (head->next->next) {
        head = head->next;
    }
    return head;
}

// удаление последнего элемента

int popBack(Node **head) {
    Node *pFwd = NULL;
    Node *pBwd = NULL;
    if (!head) {
        exit(-1);
    }
    if (!(*head)) {
        exit(-1);
    }

    pFwd = *head;
    while (pFwd->next) {
        pBwd = pFwd;
        pFwd = pFwd->next;
    }

    if (pBwd == NULL) {
        free(*head);
        *head = NULL;
    } else {
        free(pFwd->next);
        pBwd->next = NULL;
    }
}

// получение длины списка

int getSize(Node* head){
    int size = 0;
    if (head != NULL)
    {
    size = 1 + getSize(head->next); //переход к следующему элементу
    }
    return size;
}

// вставка элемента на n-ое место

void insert(Node *head, unsigned n, int val) {
    unsigned i = 0;
    Node *tmp = NULL;
    while (i < n && head->next) {
        head = head->next;
        i++;
    }
    tmp = (Node*) malloc(sizeof(Node));
    tmp->value = val;
    if (head->next) {
        tmp->next = head->next;
    } else {
        tmp->next = NULL;
    }
    head->next = tmp;
}

// удаление элемента списка

int deleteNth(Node **head, int n) {
    if (n == 0) {
        return pop(head);
    } else {
        Node *prev = getNth(*head, n-1);
        Node *elm  = prev->next;
        int val = elm->value;

        prev->next = elm->next;
        free(elm);
        return val;
    }
}

// удаление списка

void deleteList(Node **head) {
    Node* prev = NULL;
    while ((*head)->next) {
        prev = (*head);
        (*head) = (*head)->next;
        free(prev);
    }
    free(*head);
}

// создать список из массива

void fromArray(Node **head, int *arr, size_t size) {
    size_t i = size - 1;
    if (arr == NULL || size == 0) {
        return;
    }
    do {
        push(head, arr[i]);
    } while(i--!=0);
}

// возврат массива элементов хранящихся в списке

int* toArray(const Node *head) {
    int leng = sizeof(head);
    int *values = (int*) malloc(leng*sizeof(int));
    while (head) {
        values[--leng] = head->value;
        head = head->next;
    }
    return values;
}

// печать содержимого списка

void printLinkedList(const Node *head) {
    while (head) {
        printf("%d ", head->value);
        head = head->next;
    }
    printf("\n");
}

void main() {
    Node* head = NULL;
    int arr[] = {1,2,3,4,5,6,7,8,9,10}; // изначальный список элементов
    fromArray(&head, arr, 10);

    int status = 0;
    int index,number;
    while (1){
        printf("pushBack - 1, insert - 2, delete - 3, printList - 4\n");
        scanf("%d",&status);
        switch(status){
        case 1:
            printf("Enter your number:\n");
            scanf("%d",&number);
            pushBack(head,number);
            break;
        case 2:
            printf("Enter your index:\n");
            scanf("%d",&index);
            printf("Enter your number:\n");
            scanf("%d",&number);
            if (index == 0){
                push(&head,number);
                break;
            }else if (index >= GetSize(head) || index < 0){
                printf("Error, wrong index.\n");
            }else{
                insert(head,index-1,number);
            }
            break;
        case 3:
            printf("Enter your index:\n");
            scanf("%d",&index);
            if (index > GetSize(head) || index < 0){
                printf("Error, wrong index.\n");
            }else{
                deleteNth(&head,index-1);
            }
            break;
        case 4:
            printLinkedList(head);
            break;
        default:
            printf("Bye bye!");
            return 0;
        }

    }
    deleteList(&head);

    getch();
}