准备☞ 算法和数据结构(一 链表及其翻转)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Ghost_tal/article/details/82143014

链表

链表应该是面试时被提及的最频繁的数据结构。链表是由指针把若干个结点连接成链状结构。链表的创建,插入结点,删除结点等操作都只需要20行左右的代码就能实现,比较适合面试。

题目:输入一个链表的头结点,从尾到头 反过来打印出每个结点的值。要求不改变链表的结构。

思路:
通过递归来实现反过来输出链表,当访问到一个结点的时候,先递归输出它后面的结点,在输出结点本身,这样就可以输出反过来的链表了

单链表:

#define _CRT_SECURE_NO_WARNINGS 
#include <iostream>
using namespace std;


//单链表结点翻转 - 递归
typedef struct ListNode {
    int key;
    struct ListNode * next;
}ListNode;

#define LISTSIZE 1000
ListNode ListNodePool[LISTSIZE];//创建结点池,在需要的时候直接获取,比new ListNode时间快
int NodeNum = 0;
//nil是表头,NIL是它的指针,绑定一下
ListNode nil;
ListNode * NIL;

ListNode * getNewNode(){
    return &ListNodePool[NodeNum++];
}

void listInit(){
    NIL = &nil;
    NIL->next = NULL;
    NIL->key = 0;
}
//dstNode是一个指向指针的指针,,如果插入的链表是一个空链表的时候,新插入的结点就是链表的头指针,这时会
//改变头指针,因此必须吧dstNode参数设置为指向指针的指针,否则在这个函数范围外,dstNode 仍然是一个空指针。
void singleListInsterAfter(ListNode ** dstNode, ListNode * NewNode) {
    if (*dstNode == NULL) {
        *dstNode = NewNode;
    }
    else {
        ListNode  * tempNode =  * dstNode;
        while (tempNode ->next != NULL) {//找到尾结点
            tempNode = tempNode->next;
        }
        tempNode->next = NewNode;
    }
}

int data[LISTSIZE];


void showList(){
    ListNode * curNode = NIL->next;
    while (curNode != NULL){
        printf("%d ", curNode->key);
        curNode = curNode->next;
    }
    printf("\n");
}


void PrintListReversingling_Recursively(ListNode * pHead) {
    if (pHead != NULL) {
        if (pHead->next != NULL) {
            PrintListReversingling_Recursively(pHead->next);
        }
        printf("%d ", pHead->key);
    }
}

void main(){
    freopen("input.txt", "r", stdin);
    int N;
    scanf("%d", &N);

    for (int i = 0; i < N; i++){
        scanf("%d", &data[i]);
        //printf("%d ", data[i]);
    }
    printf("\n");

    listInit();

    for (int i = 0; i < N; i++){
        ListNode * node = getNewNode();
        node->key = data[i];
        singleListInsterAfter( &NIL->next, node);
    }
    //按照插入的顺序输出
    showList();
    //翻转单链表
    ListNode * pHead = NIL;
    PrintListReversingling_Recursively(pHead->next);
}

双链表:

#define _CRT_SECURE_NO_WARNINGS 
#include <iostream>
using namespace std;

//LinkedList API
//双链表结点 从尾到头打印链表
typedef struct ListNode {
    int key;
    struct ListNode * next;
    struct ListNode * prev;
}ListNode;

#define LISTSIZE 1000
ListNode ListNodePool[LISTSIZE];//创建结点池,在需要的时候直接获取,比new ListNode时间快
int NodeNum = 0;
//nil是表头,NIL是它的指针,绑定一下
ListNode nil;
ListNode * NIL;

ListNode * getNewNode(){
    return &ListNodePool[NodeNum++];
}

void listInit(){
    NIL = &nil;
    NIL->next = NIL;
    NIL->prev = NIL;
    NIL->key = 0;
}

void listInsertAfter(ListNode * dstNode, ListNode * NewNode){
    NewNode->next = dstNode->next;
    NewNode->prev = dstNode;
    dstNode->next = NewNode;
    NewNode->next->prev = NewNode;
}


//end of LinkedList API

int data[LISTSIZE];

void showList(){
    ListNode * curNode = NIL->next;
    while (curNode != NIL){
        cout << curNode->key << " ";
        curNode = curNode->next;
    }
    cout << endl;
}


void PrintListReversingling_Recursively(ListNode * pHead) {
    if (pHead != NIL) {
        if (pHead->next != NIL) {
            PrintListReversingling_Recursively(pHead->next);
        }
        printf("%d ", pHead->key);
    }
}

void main(){
    freopen("input.txt", "r", stdin);
    int N;
    scanf("%d", &N);

    for (int i = 0; i < N; i++){
        scanf("%d", &data[i]);
        //printf("%d ", data[i]);
    }

    printf("\n");

    listInit();
    for (int i = 0; i < N; i++){
        ListNode * node = getNewNode();
        node->key = data[i];
        listInsertAfter(NIL->prev, node);//NIL->prev 尾节点
    }
    //按照插入的顺序输出
    ListNode * curNode = NIL->next;
    while (curNode != NIL){
        cout << curNode->key << " ";
        curNode = curNode->next;
    }
    cout << endl;
    ListNode * pHead = NIL;
    PrintListReversingling_Recursively(pHead->next);
}

a. 创建:10个随机的数字,将其插入到链表中

b. 遍历:将这10个数字按照插入顺序输出

c. 添加、删除:使用插入排序的方法调整链表节点的顺序,使得节点按值的升序排列

//LinkedList API
//双向链表结点
typedef struct ListNode {
    int key;
    struct ListNode * next;
    struct ListNode * prev;
}ListNode;

#define LISTSIZE 1000
ListNode ListNodePool[LISTSIZE];//创建结点池,在需要的时候直接获取,比new ListNode时间快
int NodeNum = 0;
//nil是表头,NIL是它的指针,绑定一下
ListNode nil;
ListNode * NIL;

ListNode * getNewNode(){
    return &ListNodePool[NodeNum++];
}

void listInit(){
    NIL = &nil;
    NIL->next = NIL;
    NIL->prev = NIL;
    NIL->key = 0;
}

void listInsertAfter(ListNode * dstNode, ListNode * NewNode){
    NewNode->next = dstNode->next;
    NewNode->prev = dstNode;
    dstNode->next = NewNode;
    NewNode->next->prev = NewNode;
}

void listInsertAtFront(ListNode * node){
    listInsertAfter(NIL, node);
}

void listDelete(ListNode * node){
    node->prev->next = node->next;
    node->next->prev = node->prev;
}

ListNode * listSearch(int k){
    ListNode * x = NIL->next;
    while (x != NIL && x->key != k){
        x = x->next;
    }
    return x;
}

//end of LinkedList API

int data[LISTSIZE];

void insertSort(int data[], int N){
    for (int i = 1; i < N; i++){
        int key = data[i];
        int j;
        for (j = i - 1; j >= 0; j--){
            if (data[j] > key){
                data[j + 1] = data[j];
            }
            else{
                break;
            }
        }
        data[j + 1] = key;
    }
}

void showData(int N){
    for (int i = 0; i < N; i++){
        cout << data[i] << " ";
    }
    cout << endl;
}

void showList(){
    ListNode * curNode = NIL->next;
    while (curNode != NIL){
        cout << curNode->key << " ";
        curNode = curNode->next;
    }
    cout << endl;
}

void listInsertSort(){

    ListNode * curNode = NIL->next->next;
    ListNode * tmpNode;
    while (curNode != NIL){
        //cout << curNode->key << " " << endl;
        ListNode * dstNode = NIL->next;
        while (dstNode != curNode && dstNode->key < curNode->key){
            dstNode = dstNode->next;
        }
        dstNode = dstNode->prev;


        tmpNode = curNode->next;
        listDelete(curNode);
        listInsertAfter(dstNode, curNode);

        curNode = tmpNode;
    }
}


void main(){
    freopen("input.txt", "r", stdin);
    int N;
    scanf("%d", &N);

    for (int i = 0; i < N; i++){
        /*cin >> data[i];
        cout << data[i] << " ";*/
        scanf("%d", &data[i]);
        //printf("%d ", data[i]);
    }
    //cout << endl;
    printf("\n");

    listInit();
    ListNode * dstNode = NIL;
    for (int i = 0; i < N; i++){
        ListNode * node = getNewNode();
        node->key = data[i];

        listInsertAfter(NIL->prev, node);
        //dstNode = dstNode->next;
    }
    //按照插入的顺序输出
    ListNode * curNode = NIL->next;
    while (curNode != NIL){
        cout << curNode->key << " ";
        curNode = curNode->next;
    }
    cout << endl;
    //插入按照从小到大排序输出,数组实现
    insertSort(data, N);
    showData(N);
    //插入按照从小到大排序输出,链表实现
    listInsertSort();
    showList();
}

猜你喜欢

转载自blog.csdn.net/Ghost_tal/article/details/82143014
今日推荐