對於單向鏈表的10幾種常用算法(c語言)

如果要看C++版本的,請轉

https://blog.csdn.net/gs1069405343/article/details/90380355

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

}

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章