一、 链式存储
以结点的形式存储数据。除了存放一个结点的信息外,还需附设指针。
数据在内存中存储是不连续的,每个结点只能也只有它能知道下一个结点的存储位置。
二、单链表
单链表是线性表链式存储的一种,其储存不连续。单链表的数据结构中包含两个变量:数据和指向下一结点的指针。一个结点只知道下一个结点的地址。一个单链表必须有一个头指针,指向单链表中的第一个结点。否则链表会在内存中丢失。
三、单链表的操作和实现
1、单链表定义
2、创建一个空链表
3、打印链表
4、查找数据值为x的结点
5、查找索引值为index的结点
6、在i位置插入一个结点
7、在数据y之后插入一个x结点
8、删除i位置的结点
9、删除值为x的结点
1、单链表定义
- typedef int datatype;
-
- typedef struct link_node{
- datatype info;
- struct link_node* next;
- }node;
2、创建一个空链表
- #include"linklist.h"
-
- node* init_linklist(){
- return NULL;
- }
3、打印链表
- #include"linklist.h"
-
- void display_link_list(node *head){
- if(head == NULL){
- printf("the list is empty!\n");
- }else{
- node *ptr = head;
- while(ptr){
- printf("5%d",ptr->info);
- ptr = ptr->next;
- }
- }
- }
4、查找数据值为x的结点
- #include"linklist.h"
-
- node *find_node(node* head,datatype x){
- node* ptr= head;
- while(ptr && ptr->info != x)
- ptr= ptr->next;
- return ptr;
- }
5、查找索引值为index的结点
- #include"linklist.h"
-
- node* find_index(node* head,int index){
- node *ptr = head;
- int pos = 0;
- if(index<0){
- printf("Index Error\n");
- exit(1);
- }
- while(ptr && pos != index){
- ptr=ptr->next;
- pos++;
- }
- return ptr;
- }
6、在i位置插入一个结点
- #include"linklist.h"
-
- node* insert_link_list_index(node *head,int index,datatype x){
- if(index<0){
- printf("index error\n");
- exit(1);
- }
- if(index == 0){
- node *q = (node*) malloc(sizeof(node));
- q->info = x;
- q->next = head;
- head = q;
- return head;
- }
- else{
- node *ptr = find_node(head,index-1);
- node* q = (node*)malloc(sizeof(node));
- q->info = x;
- q->next = ptr->next;
- ptr->next = q;
- return head;
- }
- }
7、在数据y之后插入一个x结点
- #include"linklist.h"
-
- node* intsert_node_yx(node *head,datatype x,datatype y){
- node *q=find_node(head,y);
- if(!q){
- printf("not found the node %d\n");
- return head;
- }
- node *p = (node*)malloc(sizeof(node));
- p->info = x;
- p->next= q->next;
- q->next = p;
- return head;
- }
8、删除i位置的结点
- #include"linklist.h"
-
- node* del_link_list_index(node* head,int index){
- if(!head){
- printf("the list is empty\n");
- return head;
- }
- node* p=head,*q=NULL;
- if(index == 0){
- head = head->next;
- }else{
- p=find_index(head,index-1);
- if(p && p->next){
- q = p->next;
- p->next= q->next;
- }else{
- printf("the index is not exit\n");
- return head;
- }
- }
- free(q);
- return head;
- }
9、删除值为x的结点
- #include"linklist.h"
-
- node* del_link_list_node(node* head,datatype x){
- if(!head){
- printf("the list is empty\n");
- return head;
- }
- node* ptr=head,*pre=NULL;
- while(!ptr && ptr->info != x){
- pre = ptr;
- ptr=ptr->next;
- }
- if(!ptr){
- printf("no data\n");
- }else if(pre){
- head=ptr->next;
- }else{
- pre->next= ptr->next;
- }
- free(ptr);
- return head;
- }
三、带头结点的单链表
头结点的单链表中,head指示的是所谓的头结点,它不是实际的结点,不是用来储存数据的。可以这样理解,头结点牺牲了一个储存单元,来化简代码,因为头不可能为空了。或者用来存储一些全局量,比如链表长度,这要依具体需求而定。
四、带头结点的单链表操作实现
因为结构有变化,所以实现有变化但是变化并不多。
1、创建一个空链表
2、打印链表
3、删除值为x的结点
1、创建一个空链表
- #include"linklist.h"
-
- node* init_hlink_list(){
- node *head;
- head=(node*)malloc(sizeof(node));
- head->next=NULL;
- return head;
- }
2、打印链表
- #include"linklist.h"
-
- void display_link_list(node *head){
- if(head->next == NULL){
- printf("the list is empty!\n");
- }else{
- node *ptr = head->next;
- while(ptr){
- printf("5%d",ptr->info);
- ptr = ptr->next;
- }
- }
- }
3、删除值为x的结点
- #include"linklist.h"
-
- node* del_link_list_node(node* head,datatype x){
- if(!head->next){
- printf("the list is empty\n");
- return head;
- }
- node* ptr=head->next,*pre=head;
- while(!ptr && ptr->info != x){
- pre = ptr;
- ptr=ptr->next;
- }
- if(ptr){
- printf("no data\n");
- }else {
- pre->next= ptr->next;
- }
- free(ptr);
- return head;
- }
五、循环单链表
链表中最后一个结点的指针指向第一个结点。在这个链表中,若首指针为head,最后一个结点的判断条件为:p->next == head。
六、循环单链表的操作和实现
1、打印链表
2、获得最后一个结点
3、找到值为x的结点
4、在i位置插入一个结点
5、在数据y之后插入一个x结点
6、删除值为x的结点
1、打印链表
- #include"linklist.h"
-
- void display_link_list(node *head){
- if(head == NULL){
- printf("the list is empty!\n");
- }else{
- node *ptr = head->next;
- printf("%5d",head->info);
- while(ptr != head){
- printf("5%d",ptr->info);
- ptr = ptr->next;
- }
- }
- }
2、获得最后一个结点
- #include"linklist.h"
-
- node* get_rear(node *head){
- node* ptr = head;
- while(ptr &&ptr->next != head) {
- ptr= ptr->next;
- }
- return head;
- }
3、找到值为x的结点
- #include"linklist.h"
-
- node *find_node_clink(node* head,datatype x){
- node*ptr = head->next;
- if(head->info != x){
- while(ptr != head && ptr->info != x){
- ptr= ptr->next;
- }
- if(ptr == head){
- ptr = NULL;
- }
- return ptr;
- }else{
- return head;
- }
- }
4、在i位置插入一个结点
- #include"linklist.h"
-
- node* insert_link_list_index(node *head,int index,datatype x){
- if(index<0){
- printf("index error\n");
- exit(1);
- }
- if(index == 0){
- node *p = (node*) malloc(sizeof(node));
- node *rear;
- p->info = x;
- if(!head){
- head = p;
- p->next = head;
- return head;
- }else{
- rear = get_rear(head);
- rear->next = p;
- p->next = head;
- head = p
- return head;
- }
- }
- else{
- node *ptr= find_node(head,index-1);
- node* q = (node*)malloc(sizeof(node));
- q->info = x;
- q->next = ptr->next;
- ptr->next = q;
- return head;
- }
- }
5、在数据y之后插入一个x结点
- #include"linklist.h"
-
- node* intsert_node_yx(node *head,datatype x,datatype y){
- node *q=find_node_clink(head,y);
- if(!q){
- printf("not found the node %d\n");
- return head;
- }
- node *p = (node*)malloc(sizeof(node));
- p->info = x;
- p->next= q->next;
- q->next = p;
- return head;
- }
6、删除值为x的结点
- #include"linklist.h"
-
- node* del_link_list_node(node* head,datatype x){
- if(!head){
- printf("the list is empty\n");
- return head;
- }
- node* ptr=head,*pre=NULL;
- while(ptr->next != head && ptr->info != x){
- pre = ptr;
- ptr=ptr->next;
- }
- if(ptr->info != x){
- printf("no data\n");
- }else if(!pre){
- pre = get_rear(head);
- head=ptr->next;
- pre->next =ptr;
- }else{
- pre->next= ptr->next;
- }
- free(ptr);
- return head;
- }