数据结构 - 单链表
来源:互联网 发布:知乎的live 编辑:程序博客网 时间:2024/04/27 23:52
1.用头指针head(头指针)标示一个单链表,单链表中L表示头结点的地址,头结点的指针域指向第一个结点,头结点的数据域无意义,可存储结点的数量。(链栈不需要头结点)
2.判断链表为空 :head ->next = NULL ;
3.指向头结点的尾结点,循环链表
4.单链表逆置,头插法
5.链表的尾插:定义指针,且指针总是指向链表末尾
6.单链表特点:
1>逻辑关系相邻的元素在物理位置上可以不相邻 2>表中的元素只能顺序访问而不能随机访问 3>表的大小可以动态改变 4>插入删除等操作只需要修改指针而无需移动元素。
#include <stdio.h>#include <stdlib.h>#define TURE (1)#define FALSE (0)typedef unsigned char Boolean;typedef struct List_node{ int data; struct List_node* next; //还不存在别名}List_node;//struct List_node 的别名为List_nodetypedef List_node* List_head;List_node * Malloc(int size){ List_node *result = (List_head)malloc(size); if(result == NULL){ printf("memery is full.\n"); exit(1); } return result;}//链表初始化 定义头指针 产生头结点 并让头指针只想头结点List_head init_list(void){ List_head lhead = NULL; lhead = Malloc(sizeof(List_node)); lhead->data = 0; lhead->next = NULL; return lhead;}// 链表的销毁 1.先销毁所有结点内容 free(结点地址)//2.最后置空链表头指针*phead = NULL 故要传入头指针的地址pheadvoid disdory_list(List_head * phead){ List_node *p = NULL; List_node *q = NULL; if(phead == NULL || *phead == NULL) { return; } p = *phead; //p为头指针 头结点的地址 while(p != NULL) { q = p; p = p->next; free(q); } *phead = NULL;}//链表的头插Boolean push_front(List_head head,int value){ List_node * node = NULL; if(head == NULL) { return FALSE; } node = Malloc(sizeof(List_node)); node->data = value; node->next = head->next; head->next = node; head->data++; return TURE;}//链表的输出void print_List(List_head head){ // List_head p = head->next; // while( p != NULL){ // printf("%d ",p->data); // p = p->next; //} //注意区分 p = head->next 其中p为地址head对应结点的指针域, //为第二个结点的地址, //head->data,head->next (p = head->next) p->data,p->next List_node *p = NULL; for( p = head->next; p != NULL ;p = p->next) { printf("%d ",p->data); } printf("\n"); printf("the length is %d\n",head->data);}//链表的尾插Boolean push_back(List_head head,int value){ List_node *node = NULL; List_node *p = NULL; if(head == NULL) { return FALSE; } p = head -> next; node = Malloc(sizeof(List_node)); while(p->next != NULL) { p = p->next; } node->data = value; node->next = NULL; p->next = node; head->data++; return TURE;}//链表的头删Boolean delect_front(List_head head){ List_node *p = NULL; if(head == NULL){ return FALSE; } p = head->next; head->next = head->next->next; //删除结点直接free即可 free(p); head->data--; return TURE;}//链表的尾删Boolean delect_back(List_head head){ List_node *p = NULL; List_node *q = NULL; if(head == NULL){ return FALSE; } p = head->next; while( p->next->next != NULL) { p = p->next; } q = p; p = p->next; q ->next = NULL; free(p); head->data--; return TURE;}//指定结点的删除Boolean delect_node(List_head head,int value){ List_node *p = NULL; List_node *q = NULL; if(head == NULL){ return FALSE; } p = head; while( p != NULL && p->next != NULL) { if(p->next->data == value){ q = p->next; p->next = p->next->next; free(q); head->data--; } p = p->next; } return TURE;}//制定值的地址 经过输出结点地址,然后作出对特定值结点地址的修改Boolean changeAddr_node(List_head head,int value){ List_node *p = NULL; List_node *q = NULL; List_node *pnode = NULL; if(head == NULL){ return FALSE; } p = head; while(p->next != NULL ) { if(p->next->data == value){ q = p->next; pnode = (List_node*)realloc(NULL ,sizeof(List_node)); printf("%p\n",&pnode); pnode->next = p->next->next; pnode->data = value; p->next = pnode; free(q); break; } p = p->next; } return TURE;}//链表的升序排序 在小数据本数据的后面插,在大于本数据的前面插List_node* sort_grow(List_head head){ int temp = 0; List_node *p = NULL; List_node *q = NULL; List_node *ptr = NULL; if(head == NULL){ return FALSE; } p = head->next; head->next = NULL; while(p != NULL){ temp = 0; q=p; p=p->next; if(head->next == NULL) { head->next = q; q->next = NULL; ptr = head->next; continue; }// \|/(插入node q)///////////////////////////////head -> big node1 -> big node2 -> NULL///////////////////// if(ptr->data > q->data) { q->next = ptr; head->next= q; ptr = head->next; continue; } // \|/(插入node q)////////////////////// head -> little node1 -> little node2 -> big node3 ////////// while( temp == 0){ if(ptr ->next != NULL && ptr->data < q->data && ptr->next->data >= q->data){ q->next = ptr->next; ptr->next = q; ptr = head->next; temp ++; break; }else if(ptr->next == NULL && ptr->data <= q->data){ // \|/(插入 node q) ///////////////////////head -> little node1 ->little node2 -> NULL//////////////////////////////// q->next = NULL; ptr->next = q; ptr = head->next; temp ++; break; } ptr = ptr->next; } if(temp == 1){ continue; } } return head;}//链表的降序排序(升序链表的逆序)List_node * sort_low(List_head ghead){ List_node *p = NULL; List_node *q = NULL; if(ghead == NULL) { return FALSE; } p = ghead->next; ghead->next = NULL; while(p != NULL) { q = p; p = p -> next; //想让结点p后移向下一个结点,防止p的next改变 q->next = ghead->next; ghead->next = q; //p = p->next; 若将while中第二行写在此处,由于P Q两个结点是同一个结点,故修改了q结点的next, //同时是的p结点的next值也发生改变 } return ghead;}//删除多个List_node* movemore_node(List_head head,int left,int right) //从第一个结点开始计算{ int count = 0; int i = 0; int j = 0; if(head == NULL){ exit(1); } List_node *p = NULL; List_node *q = NULL; p = head->next; for(i = 1;i < left-1; ++i){ if(p != NULL){ p = p->next; }else{ printf("第%d个结点不存在\n",left); return head; } } q = p; for(j = 0;j <=(right - left) + 1;++j){ if(q != NULL) { q = q->next; count++; }else{ p->next = NULL; head->data -= (count-1); printf("第%d个结点不存在\n",right); return head; } } p->next = q; head->data -= ((right - left)+1); return head;}int main(int ac,char ** av){ int i = 0,j = 0; List_head head = NULL; List_head ghead = NULL; List_head lhead = NULL; List_head mhead = NULL; head = init_list(); for(i = 0;i < 10;++i) { push_front(head,rand() % 10); } for(j = 0;j < 5;++j) { push_back(head,rand() % 100); } print_List(head); push_front(head,12); print_List(head); //delect_front(head); delect_back(head); delect_node(head,3); print_List(head); //changeAddr_node(head,9); ghead = sort_grow(head); print_List(ghead); lhead = sort_low(ghead); print_List(lhead); mhead = movemore_node(lhead,5,7); //从第一个结点开始,删除第4,5,6,个结点 print_List(mhead); //disdory_list(&head); return 0;}
单链表的逆置:
void reverse(NodeType *H){ Nodetype *p = NULL; Nodetype *q = NULL; p = H->next; H->next = NULL; while(p != NULL){ //p指向下一个元素 q=p; p = p->next; //防断链 q->next = H->next; H->next = q; }}
单链表的算法:连接两个递增的单链表l1,l2, 并让其递增排列,算法如下: //尾插案例
void sort_link(Lnode *l,Lnode *l1){ Lnode *p = l->next; Lnode *q = l1->next; l->next = NULL; Lnode *m = l; free(l1); while(p != NULL && q != NULL) { if(p->data >= q->data) { m->next = p; p = p->next; }else{ m->next = q; q = q->next; } m = m->next; m->next = NULL; } if(p == NULL) { m->next = q; }else{ m->next = p; }}
0 0
- 数据结构---单链表
- 数据结构--单链表
- 数据结构单链表
- 数据结构单链表
- 【数据结构】单链表
- 数据结构单链表
- [数据结构]单链表
- 数据结构--单链表
- 数据结构--单链表
- 数据结构-单链表
- 数据结构 -- 单链表
- 数据结构-单链表
- 数据结构 --- 单链表
- 数据结构---单链表
- 数据结构--单链表
- 数据结构 单链表
- 数据结构-单链表
- 数据结构---单链表
- Huawei LiteOS内核剖析0--启动
- #windows下搭IPython notebook环境
- Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum(离线线段树)
- Android开发--重点知识汇总(持续更新)
- js(javaScript)学习系列--DOM
- 数据结构 - 单链表
- android 关于FragmentPagerAdagter页面切换更新及页面切换后重新加载数据,或不执行onResume
- 6w4:第六周程序填空题1(虚函数与派生)
- cookie、session、sessionid 与jsessionid
- git分支问题
- getWritableDatabase()和getReadableDatabase()方法区别
- 常用正则表达式
- 接口
- Java线程池原理与实例详解