链表简单整理

tags:C

链表

by – catherine

  • 链表
      • 中序遍历
      • 深度二叉搜索
      • 排序链表
      • 最开始做的比较简单的链表题目
      • 环形链表
      • 小感想

【本人学院】(http://sdcs.sysu.edu.cn/)

1.中序遍历

要实现两个函数,函数buildTree通过读入一串整数以层次优先从左到右的方式构建一个二叉树,函数outputTree输出此树的中序遍历。两个函数的原型如下:

void buildTree(BN** rootptr);

void outputTree(BN* root);

输入:N个正整数,1<=N<=30,以空格间隔,以-1结束。注意-1不包含在此树的结构中,只是作为输入结束的符号。

输出:一行按照中序遍历排列的正整数,以空格间隔,最后一个输出的元素后仍然有空格,且没有换行

注意:main函数已经给出,并且在其中给出了树的根节点的指针以及整棵树free的过程,buildTree函数内所有的结点应以malloc形式生成,如果一个结点没有左儿子或者右儿子,则相应的指针应该等于NULL。

Sample:

input:

1 2 3 4 5 6 7 8 9 -1

output:

8 4 9 2 5 1 6 3 7

//中序遍历链表实现
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

typedef struct BN {
    int n;
    struct BN *left;
    struct BN *right;
} BN;

void buildtree(BN **root) {
    BN **que[50];
    BN forstyle = {1, NULL, NULL};
    int head = 0, tail = 1, t;
    que[0] = root;
    scanf("%d", &t);
    while (t != -1) {
        *que[head] = malloc(sizeof(forstyle));
        (*que[head])->n = t;
        que[tail] = &((*que[head])->left); tail = (tail + 1)%50; que[tail] = &((*que[head])->right); tail = (tail + 1)%50; head = (head + 1)%50; scanf("%d", &t); } while (head != tail) { *que[head] = NULL; head = (head + 1)%50; } return; } void printtree(BN *root) { if (root == NULL) return; else { printtree(root->left); printf("%d ", root->n); printtree(root->right); } } int main() { BN *root = NULL; BN *que[50]; int head = 0, tail = 1; buildtree(&root); printtree(root); que[0] = root; while (head != tail) { if (que[head]->left != NULL) { que[tail] = que[head]->left;
        tail = (tail + 1)%50;
        }
        if (que[head]->right != NULL) {
        que[tail] = que[head]->right;
        tail = (tail + 1)%50;
        }
        free(que[head]);
        head = (head + 1)%50;
    }
    return 0;
}

2.深度二叉搜索

即后序遍历,先访问节点,再访问左子树,然后访问右子树。
第一行输入n
接下来有n个数
输入要搜索的数

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

void dfs(int a[], int l, int index, int find) {
    if (index < l) {
        if (a[index] != find) {
        printf("%d ", a[index]);
        dfs(a, l, 2*index + 1, find);
        dfs(a, l, 2*index + 2, find);
        } else {
        printf("%d\n", find);
        exit(1);
        }
    }
    return;
}

int main() {
    int n, a[100], number, i;
    scanf("%d", &n);
    for (i = 0; i < n; i++) 
    scanf("%d", &a[i]);
    scanf("%d", &number);
    dfs(a, n, 0, number);
    return 0;
}

3.排序链表

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

typedef struct node {
int n;
struct node *left;
struct node *right;
} node;

node *init(int num) {
    node *root = malloc(sizeof(struct node));
    root->left = root->right = NULL;
    root->n = num;
    return root;
}

node *creat(int num) {
    node *temp = malloc(sizeof(struct node));
    temp->left = temp->right = NULL;
    temp->n = num;
    return temp;
}
void insert(node *root, int num) {
    if (num < root->n) {
        if (root->left == NULL) root->left = creat(num);
        else insert(root->left, num);
    }
    if (num > root->n) {
        if (root->right == NULL) root->right = creat(num);
        else insert(root->right, num);
    }
}
void printtree(node *root) {
     if (root->left != NULL) printtree(root->left);
     printf("%d ", root->n);
     if (root->right != NULL) printtree(root->right);
     return;
}
void freetree(node *root) {
     if (root->left != NULL) freetree(root->left);
     if (root->right != NULL) freetree(root->right);
     free(root);
}
int main() {
    node *root = NULL;
    int n, value, i;
    scanf("%d", &n);
    for (i = 0; i < n; i++) {
        scanf("%d", &value);
        if (i == 0) root = init(value);
        else insert(root, value);
    }
    printtree(root);
    freetree(root);
    return 0;
}

4.最开始做的比较简单的链表题目

第一行输入n,表示有n组数据
接下来有n行,每行输入序号和字母分数
输入学号m, 输出前一个的字母分数

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

typedef struct node {
   int n;
   char c;
   struct node *next;
} node;

int main() {
    int i, n;
    char b;
    node list[100];
    scanf("%d", &n);
    for (i = 0; i < n; i++) {
    scanf("%d %c", &list[i].n, &list[i].c);
    if (i == 0) list[i].next = NULL;
    else list[i].next = &list[i - 1];
    }
    getchar();
    scanf("%c", &b);
    list[0].next = &list[n - 1];
    for (i = 0; i < n; i++)
    if (list[i].c == b) printf("%d\n",  list[i].next->n);
    return 0;
}

5.环形链表

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

typedef struct node {
int num;
struct node *prev;
struct node *next;
} node;

node *add(node *first, int n) {
     if (first == NULL) {
     first = (node*)malloc(sizeof(node));
     first->num = n;
     first->prev = first->next = first;
     return first;
     }
     node *p = first->prev;
     node *q = first;
     node *temp;
     temp = (node *)malloc(sizeof(node));   // 环形链表,注意(p->prev = temp, q->next = temp)会出现段错误。
     temp->num = n;
     temp->next = q;
     temp->prev = p;
     p->next = temp; 
     q->prev = temp;
     first = temp;
     return first;
}
void print(node *first) {
    if (first == NULL) return;
    node *p;
    p = first->prev;
    p->next = NULL;
    p = first;
    while (p != NULL) {
    printf("%d\n", p->num);
    p = p->next;
    }
    return;
}
int main() {
    int i, n, value;
    node *first = NULL;
    scanf("%d", &n);
    for (i = 0; i < n; i++) {
    scanf("%d", &value);
    first = add(first, value);
    }
    print(first);
    return 0;
}

小感想

链表是比较重要,也是比较难的一部分,尤其是与重要的指针结合到了一起,所以就显得更加有难度。然而熟能生巧,打多了自然会有感觉,其中也是有规律可循的。

你可能感兴趣的:(C语言)