说明
在算法实现中,经常会有需要每次取出最小(或最大)的数据,这时就需要有一个辅助的数据结构能够提供这个最小(或最大数据)。有序链表是实现最简单最方便的一个数据结构(堆会更好后面再做实现)。本例有序链表不指定数据的类型,但是需要提供数据的排序依据(为int型,即权重)。
1、结构定义
定义升序与降序常量;
定义链表结点的结构,包含数据元素地址,数据元素权重及下一节点。
定义有序链表对象结构,包含头结点指针,链表的排序方式和链表的实际大小
#define ASC 0 //定义升序
#define DESC 1 //定义降序
/**
* 有序链表
*/
typedef struct ListNode{
void* data;
int weight;
struct ListNode *next;
//struct ListNode *head;
}ListNode;
typedef struct SortedLinkedList{
ListNode *head; //有序链表头节点,头结点只用来占位,不用于实际存储
int sortType; //排序方式 0|升序,1|降序
int size; //大小
}SortedLinkedList;
2、创建有序链表
根据传入的排序方式,创建有序链表;链表的头节点固定,且不用于存储数据。
/**
* 创建有序链表
* sortType 排序方式 0|升序,1|降序
**/
SortedLinkedList* createSortedLinkedList(int sortType){
SortedLinkedList *list = (SortedLinkedList*)malloc(sizeof(SortedLinkedList));
ListNode *head = (ListNode*)malloc(sizeof(ListNode));
head->next = NULL;
list->head = head;
list->sortType = sortType;
list->size = 0;
return list;
}
3、链表是否为空
/**
* 链表是否为空
*/
int sortedLinkedListIsEmpty(SortedLinkedList *list){
return list->size == 0?1:0;
}
4、查询指定权重所处的位置(有序链表内部调用)
传入有序链表对象,和新数据的权重,获取到合适的位置并返回节点
/**
* 查询指定权重值所处的位置(仅在有序链表内部调用)
* head 起始位置,weight 指定权重,sortType 排序方式
* return 返回可以插入位置的前驱节点
*/
ListNode* searchWeightSeat(ListNode *head,int weight,int sortType){
while(head->next != NULL){
if(sortType == ASC){
if(head->next->weight >= weight){//权重值 大于等于 下一节点的权重,那就插入当前节点后,即下一节点前
return head;
}else{
head = head->next;
}
}else{
if(head->next->weight <= weight){//权重值 小于等于 下一节点的权重,那就插入当前节点后,即下一节点前
return head;
}else{
head = head->next;
}
}
}
return head;
}
5、添加数据
传入有序链表对象,数据元素和数据元素的权重,将元素添加到有序链表中。
/**
* 有序链表插入数据
* list 链表对象,data 数据元素,weight 新元素权重
**/
void sortedLinkedListAdd(SortedLinkedList *list,void *data,int weight){
ListNode *prev = searchWeightSeat(list->head,weight,list->sortType);
ListNode *node = (ListNode*)malloc(sizeof(ListNode));
node->data = data;
node->weight = weight;
node->next = prev->next;
prev->next = node;
list->size = list->size+1;
}
6、获取数据
传入有序链表,取出有序链表第一个元素(最小或最大)
/**
* 有序链表删除数据(第一个数据)
* list 链表对象
**/
void* sortedLinkedListDelete(SortedLinkedList *list){
if(sortedLinkedListIsEmpty(list) == 1){
printf("删除失败,链表为空!\n");
return NULL;
}
ListNode *node = list->head->next;
list->head->next = node->next;
list->size--;
void* data = node->data;
free(node);
return data;
}
7、销毁有序链表
链表数据可能不为空,所以先遍历节点,释放所有链表结点空间,最后释放链表对象空间。
/**
* 销毁链表
*/
void sortedLinkedListDestroy(SortedLinkedList *list){
ListNode *node = list->head;
while(node != NULL){
ListNode *tmp = node;
node = tmp->next;
free(tmp);
}
free(list);
}
源码地址:https://download.csdn.net/download/Waiting_Love/89608763