链表
来源:互联网 发布:淘宝贷款如何开通 编辑:程序博客网 时间: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;}