链表

来源:互联网 发布:淘宝贷款如何开通 编辑:程序博客网 时间:2024/06/11 03:38

单向链表定义

对于数组,逻辑关系上相邻的连个元素的物理位置也是相邻的,这种结构的优点是可以随机存储任意位置的元素,但缺点是如果从数组中间删除或插入元素时候,需要大量移动元素,效率不高。

数组的优缺点

链式存储结构的特点,元素的存储单元可以是连续的,也可以是不连续的,因此为了表示每个元素a,与其接后的元素a+1之间的关系,对于元素a,除了存储其本身信息外,还需要存储一个指示其接后元素的位置。这两部分数据成为结点(node)。

一个结点中存储的数据元素被成为数据域。存储接后存储位置的域叫做指针域。n个结点(ai(1<=i<=n)的存储映像链接成一个链表。

整个链表必须从头结点开始进行,头结点的指针指向下一个结点的位置,最后一个结点的指针指向NULL。

在链表中,通过指向接后结点位置的指针实现将链表中每个结点“链”到一起。链表中第一个结点称之为头结点。

这里写图片描述

这里写图片描述

这里写图片描述

单向链表数据结构定义

struct list{    int data;//链表数据域    struct list *next;//链表指针域};

单向链表的实现

struct list *create_list()//建立一个节点void traverse(struct list *ls)//循环遍历链表struct list *insert_list(struct list *ls, int n, int data)//在指定位置插入元素int delete_list(struct list *ls, int n)//删除指定位置元素int count_list(struct list *ls)//返回链表元素个数void clear_list(struct list *ls)//清空链表,只保留首节点int empty_list(struct list *ls)//返回链表是否为空struct list *locale_list(struct list *ls, int n)//返回链表指定位置的节点struct list *elem_locale(struct list *ls, int data)//返回数据域等于data的节点int elem_pos(struct list *ls, int data)//返回数据域等于data的节点位置struct list *last_list(struct list *ls)//得到链表最后一个节点void merge_list(struct list *st1, struct list *ls2)//合并两个链表,结果放入st1中void reverse(struct list *ls)//链表逆置

这里写图片描述

这里写图片描述

删除元素操作

这里写图片描述

这里写图片描述

这里写图片描述

逆置链表-方式1,移动指针域

这里写图片描述

逆置链表-方式2,移动数据域

这里写图片描述

逆置操作
1.判断首节点的next是否为NULL;
2.判断首节点next的next是否为空,如果为空证明链表除首节点之外只有一个节点,所以不需要逆置;
3.定义一个指针last,指向首节点的next域,因为逆置之后,该域为链表尾节点;
4.定义三个指针,分别代表前一个节点,当前节点,下一个节点;
5.前节点指向链表首节点;
6.当前节点指向链表首节点的next域;
7.下一个节点为NULL;
8.循环条件判断当前节点是否为NULL,如果为NULL退出循环;
a)下一个节点指向当前节点的下一个节点;
b)当前节点的下一个节点指向前一个节点;
c)前一个节点指向当前节点;
d)当前节点指向下一个节点;
9.循环完成;
10.设置last节点的next为NULL;
11.设置链表首节点的next为前一个节点。

代码实现:#include <stdio.h>#include <stdlib.h>#include <memory.h>struct list {    int data;    struct list *next;};/** * 创建节点. * @return */struct list *create_list() {    struct list *p = malloc(sizeof(struct list));    memset(p, 0, sizeof(p));    return p;}/** * 指定位置插入节点. * @param ls * @param n * @param data * @return */struct list *insert_list(struct list *ls, int n, int data) {    struct list *p = ls;    while (p && n--) {        p = p->next;    }    if (p == NULL)        return NULL;    struct list *node = create_list();    memset(node, 0, sizeof(node));    node->data = data;    node->next = p->next;    p->next = node;    return node;}/** * 删除指定节点 * @param ls * @param n * @return */int delete_list(struct list *ls, int n) {    struct list *p = ls;    while (p && n--) {        p = p->next;    }    struct list *q = p->next;    int data = q->data;    p->next = q->next;    free(q);    return data;}/** * 计算列表长度. * @param ls * @return */int count_list(struct list *ls) {    // 不能算首节点.    struct list *p = ls->next;    int count = 0;    while (p) {        p = p->next;        count++;    }    return count;}void clear_list(struct list *ls) {    // 清空节点,但是不能释放头节点.    struct list *p = ls->next;    while (p) {        struct list *q = p->next;        free(p);        p = q;    }    // 重点,这里必须把首节点的next置空.    ls->next = NULL;}/** * 寻找最后一个节点 * @param ls * @return */struct list *last_list(struct list *ls) {    struct list *p = ls;    struct list *last = NULL;    while (p) {        last = p;        p = p->next;    }    return last;}/** * 合并列表 * @param st1 * @param ls2 */void merge_list(struct list *st1, struct list *ls2) {    struct list *last = last_list(st1);    last->next = ls2->next;    free(ls2);}/** * 列表翻转. * @param ls */void reverse(struct list *ls) {    struct list *pre = ls;    struct list *cur = ls->next;    struct list *next = NULL;    struct list *last = ls->next;    while (cur) {        next = cur->next;        cur->next = pre;        pre = cur;        cur = next;    }    last->next = NULL;    ls->next = pre;}// 链表的冒泡排序void bubble_sort(struct list *ls) {    int count = count_list(ls);    int i,j;    for (i = 0;  i< count; i++) {        struct list *p = ls->next;        for (j = 0; j < count - i - 1; j++) {            struct list *q = p->next;            if (p->data > q->data) {                int temp = q->data;                q->data = p->data;                p->data = temp;            }            p = q;        }    }}/** * 遍历列表 * @param ls */void traverse(struct list *ls) {    struct list *p = ls->next;    while (p) {        printf("data = %d\n", p->data);        p = p->next;    }}int main() {    int i;    struct list *first = create_list();    struct list *second = create_list();    for (i = 0; i < 10; i++) {        struct list *node = create_list();        insert_list(first, i, i);    }    for (i = 100; i < 110; i++) {        struct list *node = create_list();        insert_list(second, 0, i);    }    //clear_list(first);    printf("count = %d\n", count_list(first));    delete_list(first, 3);    //traverse(first);    printf("data = %d\n", last_list(first)->data);    printf("Hello, World!\n");    merge_list(first, second);    //traverse(first);    printf("-----------------\n");    reverse(first);    traverse(first);    printf("-----------------\n");    printf("-----------------\n");    bubble_sort(first);    traverse(first);    return 0;}
原创粉丝点击