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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gs1069405343/article/details/50471736

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;
	else
		return 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");

}






猜你喜欢

转载自blog.csdn.net/gs1069405343/article/details/50471736
今日推荐