对于单向链表的10几种常用算法

来源:互联网 发布:java程序代码及结果 编辑:程序博客网 时间:2024/06/06 19:58

list.c文件如下

#include "list.h"/*返回head链表POS节点的位置*/LINK list_moov_pos(LINK head,int pos){LINK node = head;while(--pos) node = node->pNext;  return node;}/*求链表长度*/int list_length(LINK *head){LINK node = *head;int i = 0;while(NULL != node){i++;node = node->pNext;}return i;}/* 判断链表是否为空 */bool list_empty(LINK *head){LINK node = *head;if(NULL == node)return true;elsereturn false;}/* 对链表进行冒泡排序 */LINK list_sort(LINK *head){LINK node = *head;LINK p = NULL;LINK q = NULL;LINK cache = (LINK)malloc(sizeof(LIST_DATA));if(NULL == cache) exit(-1);for (p = node; p != NULL; p = p->pNext){for (q = p->pNext; q != NULL; q=q->pNext){if ((p->data).nume > (q->data).nume){cache->data = p->data;p->data = q->data;q->data = cache->data;}}}free(cache);return node;}/*删除链表head中第POS个节点的数据*/bool list_pos_dele(LINK *head, int pos){if(NULL == *head ||(0 < pos && pos > list_length(head)))return false;if(1 == pos){LINK node = *head;*head = node->pNext;free(node);}else{ LINK pre_node = NULL, now_node= NULL;pre_node = list_moov_pos(*head,pos-1);now_node = list_moov_pos(*head,pos);pre_node->pNext = now_node ->pNext;free(now_node);}return true;}/*删除链表head头POS个删除*/bool list_head_dele(LINK *head ,int pos){if(NULL == *head || (0 < pos && pos > list_length(head)))return false;LINK node = NULL;node = list_moov_pos(*head, pos);*head=node->pNext;free(node);return true;}/*头添加*/void list_head_add(LINK *head, DATA data){if(*head == NULL){  (*head) = (LINK)malloc(sizeof(LIST_DATA));if(NULL == *head) exit(-1);(*head)->data = data;(*head)->pNext = NULL; }else{LINK add_node = NULL;add_node = (LINK)malloc(sizeof(LIST_DATA));if(NULL == add_node) exit(-1);add_node->data = data;add_node->pNext = *head;*head = add_node; }}/*尾巴添加*/void list_end_add(LINK *head, DATA data){if(*head == NULL){  (*head) = (LINK)malloc(sizeof(LIST_DATA));  if(NULL == *head) exit(-1);        (*head)->data = data; (*head)->pNext = NULL;  }else{LINK node = *head, node_add = NULL; while(node->pNext != NULL)   node = node->pNext;node_add = (LINK)malloc(sizeof(LIST_DATA));if(NULL == node_add) exit(-1);node_add->data = data;node_add->pNext = NULL;node->pNext = node_add; }} /*任意改动*/bool list_random_change(LINK *head, DATA data, int pos){if(NULL == *head || (0 < pos && pos > list_length(head)))return false;LINK node = NULL;node = list_moov_pos(*head,pos);node->data = data;return true;}/*任意节点前面插入数据*/bool list_random_insert(LINK *head, DATA data, int pos){if(NULL == *head || (0 < pos && pos > list_length(head)))return false;if(pos==1){LINK node = NULL;node = (LINK)malloc(sizeof(LIST_DATA));    if(NULL == node) exit(-1);                                  node->data = data; //将name赋值给结构体指针*head中的name。node->pNext=*head;*head = node;} else{       LINK node = NULL,add_node = NULL;       add_node = (LINK)malloc(sizeof(LIST_DATA));       if(NULL == add_node) exit(-1);       node = list_moov_pos(*head ,pos-1);       add_node->data = data;             add_node->pNext = node->pNext;       node->pNext =add_node;   } return true;}/*链表head1 和head2 各自有序,合并成一个链表依然有序(递归方法)*/LINK list_merge_recursive(LINK *head1, LINK *head2) {     LINK head = NULL;     LINK node1 = *head1;     LINK node2 = *head2;     if(node1 == NULL) return *head2;     if(node2 == NULL) return *head1;     if(node1->data.nume <= node2->data.nume) {         head = node1;         head->pNext = list_merge_recursive(&(*node1).pNext, &node2);     }else {         head = node2;         head->pNext = list_merge_recursive(&node1, &(*node2).pNext);     }     return head;}/*将链表逆序*/LINK list_reverse(LINK *head){LINK node = *head;    if( node == NULL || (*node).pNext == NULL || (*node).pNext->pNext == NULL)         return node;   /*链表为空或只有一个元素则直接返回*/     LINK t = NULL;    LINK q = node;    LINK p = (*node).pNext;     while(q != NULL){              t = q->pNext;      q->pNext = p;      p = q;      q = t;    }    /*此时q指向原始链表最后一个元素,也是逆转后的链表的表头元素*/    (*node).pNext->pNext = NULL; /*设置链表尾*/    (*node).pNext = p;           /*调整链表头*/    DATA data;    data = node->data;    list_end_add(&node,data);    list_pos_dele(&node,1);    return node;}/*连接2个链表*/LINK list_concatenate(LINK *head1,LINK *head2){if(*head1 == NULL) return *head2;if(*head2 == NULL) return *head1;    LINK node = *head1;    while(node->pNext != NULL)        node=node->pNext;    node->pNext = *head2;    return *head1;}/*销毁链表*/void list_free(LINK *head){    while(*head != NULL){        list_free(&(*head)->pNext);        free(*head);        *head = NULL;    }}
list.h文件如下

#ifndef LIST_H#define LIST_H#include <stdio.h>#include <stdlib.h>#include <assert.h>#include <string.h>#include <stdbool.h>typedef struct list{char name[1024];int  nume;}DATA;typedef struct list_all{DATA data;struct list_all *pNext;}LIST_DATA;typedef LIST_DATA* LINK;#include "list.h"/*返回head链表POS节点的位置*/LINK list_moov_pos(LINK head,int pos);/*求链表长度*/int list_length(LINK *head);/* 判断链表是否为空 */bool list_empty(LINK *head);/* 对链表进行冒泡排序 */LINK list_sort(LINK *head);/*删除链表head中第POS个节点的数据*/bool list_pos_dele(LINK *head, int pos);/*删除链表head头POS个删除*/bool list_head_dele(LINK *head ,int pos);/*头添加*/void list_head_add(LINK *head, DATA data);/*尾巴添加*/void list_end_add(LINK *head, DATA data);/*任意改动*/bool list_random_change(LINK *head, DATA data, int pos);/*任意节点前面插入数据*/bool list_random_insert(LINK *head, DATA data, int pos);/*链表head1 和head2 各自有序,合并成一个链表依然有序(递归方法)*/LINK list_merge_recursive(LINK *head1, LINK *head2);/*将链表逆序*/LINK list_reverse(LINK *head);/*连接2个链表*/LINK list_concatenate(LINK *head1,LINK *head2);/*销毁链表*/void list_free(LINK *head);#endif

main.c文件如下

#include "list.h"LINK head = NULL;void add_head()//往头添加数据{  int i;  DATA node;  for(i = 0; i < 5; i++){//连续添加5个数据    sprintf(node.name,"add head %d\0",i);    node.nume = i;    list_head_add(&head,node);   }}void add_tail()//往尾添加数据{  int i;  DATA  node;  for(i = 0; i < 5; i++){//连续添加5个数据    sprintf(node.name,"add tail %d\0",i);    node.nume = i;    list_end_add(&head,node);   }}void add_arbitrarily(int pos)//任意插入{  int i;  DATA node;  //设置要插入的数据  strcpy(node.name,"arbitrarily");  node.nume = 100;  //执行  list_random_insert(&head,node,pos);}void Any_change(int pos)//任意改动{  int i;  DATA node;  //新数据  strcpy(node.name,"Any change");  node.nume = 101;  //执行  list_random_change(&head,node,pos);}void printf_data(LINK *head){  LINK node = *head;  while(node != NULL){    printf("name=[%s] nume=[%d]\n",node->data.name,node->data.nume);    node = node->pNext;  }  printf("\n");}int main(int argc, char const *argv[]){    assert(head == NULL);//条件测试    printf("========往头部添加数据=======1\n");    add_head();    printf_data(&head);    printf("==========求链表长度=========2\n");    int len = 0;    len = list_length(&head);    printf("len = %d\n",len);      printf("===========尾部添加==========3\n");    add_tail();    printf_data(&head);    printf("====对链表进行冒泡排序=====4\n");    head = list_sort(&head);    printf_data(&head);    printf("=========任意节点前面插入========5\n");    add_arbitrarily(1);//往第一个节点前面插入数据    printf_data(&head);    add_arbitrarily(4);//往第四个节点前面插入数据    printf_data(&head);    printf("======任意节点数据改动=======6\n");    Any_change(1);    printf_data(&head);    Any_change(3);    printf_data(&head);    printf("========删除头N个数据========7\n");    list_head_dele(&head,2);//删除头2个    printf_data(&head);    printf("=====删除第POS位上的数据=====8\n");    list_pos_dele(&head,3);//删除第3个    printf_data(&head);    printf("=============倒序============9\n");    head = list_reverse(&head); /*倒序*/    printf_data(&head);     printf("=====按nume编号合并链表======10\n");    int i;    LINK test = NULL;    DATA node;    //生成新链表    for(i = 0; i < 5; i++){//连续添加5个数据      sprintf(node.name,"list merge recursive %d\0",i);      node.nume = i;      list_end_add(&test,node);     }    //head = list_merge_recursive(&head,&test);/*合并head 和 test 链表*/   // printf_data(&head);    printf("====直接按顺序连接2个链表====11\n");    /*按顺序连接2个链表*/    head = list_concatenate(&test,&head);//test 在前    printf_data(&head);     printf("======判断链表是否为空=======12\n");    if(list_empty(&head))      printf("list is NULL\n");    else      printf("list don't NULL\n");    printf("============销毁链表=========13\n");    list_free(&head);//销毁链表    printf_data(&head);     printf("======判断链表是否为空=======14\n");    if(list_empty(&head))      printf("list is NULL\n");    else      printf("list don't NULL\n");}






0 0
原创粉丝点击