三、有序链表

说明

在算法实现中,经常会有需要每次取出最小(或最大)的数据,这时就需要有一个辅助的数据结构能够提供这个最小(或最大数据)。有序链表是实现最简单最方便的一个数据结构(堆会更好后面再做实现)。本例有序链表不指定数据的类型,但是需要提供数据的排序依据(为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

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值