第六周总结02

文章介绍了Linux内核中的通用链表实现,包括节点定义、操作函数以及一个简单的链表库。此外,还讨论了数组和矩阵的概念,特别是对于稀疏矩阵的压缩存储方法,如上三角、下三角、对称和对角矩阵的压缩策略,以及无规律稀疏矩阵的三元组存储方式。
摘要由CSDN通过智能技术生成

Linux内核通用链表

  • 既然链表中的节点不能包含万物,那么就让万物包含这个节点

通用链表

  • 节点
    • void* ptr;// 数据域
    • 指针域
  • 运算
    • 常规功能 + 回调函数(函数指针那里讲过)
// 通用链表头文件
#ifndef LIST_H
#define LIST_H

#include <stdbool.h>

// 通用链表

typedef int (*Compar)(const void*,const void*);

// 链表节点
typedef struct ListNode
{
	void* ptr;
	struct ListNode* prev;
	struct ListNode* next;
}ListNode;

// 通用链表结构
typedef struct List
{
	ListNode* head;
	size_t size;
}List;

// 创建链表
List* create_list(void);
// 头添加
void add_head_list(List* list,void* ptr);
// 尾添加
void add_tail_list(List* list,void* ptr);
// 插入
bool insert_index_lsit(List* list,size_t index,void* ptr);
// 按位置删除
bool del_index_list(List* list,size_t index);
// 按值删除
bool del_value_list(List* list,void* ptr,Compar cmp);
// 查询
void* query_list(List* list,void* ptr,Compar cmp);
// 访问
void* access_list(List* list,size_t index);
// 排序
void sort_list(List* list,Compar cmp);
// 清空
void clear_lsit(List* list);
// 销毁
void destroy(List* list);
// 遍历
void show_list(List* list,void (*show)(void*));

#endif//LIST_H
#include <stdlib.h>
#include "list.h"

// 创建节点
static ListNode* create_list_node(void* ptr)
{
	ListNode* node = malloc(sizeof(ListNode));
	node->ptr = ptr;
	node->prev = node;
	node->next = node;
	return node;
}

// 创建链表
List* create_list(void)
{
	List* list = malloc(sizeof(List));
	list->head = create_list_node(NULL);
	list->size = 0;
	return list;
}

// 依赖函数
// 在两个节点之间插入一个新节点
static void _add_list(ListNode* p,ListNode* n,void* ptr)
{
	ListNode* node = create_list_node(ptr);
	p->next = node;
	n->prev = node;
	node->prev = p;
	node->next = n;
}

// 删除节点
static void _del_list(ListNode* node)
{
	node->next->prev = node->prev;
	node->prev->next = node->next;
	free(node->ptr);
	free(node);
}

// 按位置访问节点
static ListNode* _index_list(List* list,size_t index)
{
	if(index >= list->size) return NULL;
	if(index < list->size/2)
	{
		ListNode* node = list->head->next;
		while(index--) node = node->next;
		return node;
	}
	else
	{
		ListNode* node = list->head->prev;
		while(++index < list->size) node = node->prev;
		return node;
	}
}

// 头添加
void add_head_list(List* list,void* ptr)
{
	_add_list(list->head,list->head->next,ptr);
	list->size++;
}

// 尾添加
void add_tail_list(List* list,void* ptr)
{
	_add_list(list->head->prev,list->head,ptr);
	list->size++;
}

// 遍历
void show_list(List* list,void (*show)(void*))
{
	for(ListNode* n=list->head->next; n!=list->head; n=n->next)
	{
		show(n->ptr);
	}
}
// 插入
bool insert_index_lsit(List* list,size_t index,void* ptr)
{
	ListNode* node = _index_list(list,index);
	if(NULL == node) return false;

	_add_list(node->prev,node,ptr);
	list->size++;
	return true;
}

// 按位置删除
bool del_index_list(List* list,size_t index)
{
	ListNode* node = _index_list(list,index);
	if(NULL == node) return false;

	_del_list(node);
	list->size--;
	return true;
}
// 按值删除
bool del_value_list(List* list,void* ptr,Compar cmp)
{
	for(ListNode* n=list->head->next; n!=list->head; n=n->next)
	{
		if(0 == cmp(ptr,n->ptr)) 
		{
			_del_list(n);
			list->size--;
			return true;
		}
	}
	return false;
}
// 查询
void* query_list(List* list,void* ptr,Compar cmp)
{
	for(ListNode* n=list->head->next; NULL!=n; n=n->next)
	{
		if(0 == cmp(ptr,n->ptr))
		{
			return n->ptr;
		}
	}
	return NULL;
}
// 访问
void* access_list(List* list,size_t index)
{
	ListNode* node = _index_list(list,index);
	if(NULL == node) return NULL;

	return node->ptr;
}
// 排序
void sort_list(List* list,Compar cmp)
{
	for(ListNode* i=list->head->next; i->next!=list->head; i=i->next)
	{
		for(ListNode* j=i->next; j!=list->head; j=j->next)
		{
			if(1 == cmp(i->ptr,j->ptr))
			{
				void* temp = i->ptr;
				i->ptr = j->ptr;
				j->ptr = temp;
			}
		}
	}
}
// 清空
void clear_list(List* list)
{
	ListNode* n= list->head->next;
	while(n!=list->head)
	{
		ListNode* temp = n;
		n = n->next;
		free(temp->ptr);
		free(temp);
	}
	list->head->next = list->head;
	list->head->prev = list->head;
	list->size = 0;
}
// 销毁
void destroy_list(List* list)
{
	clear_list(list);
	free(list->head);
	free(list);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"

typedef struct Student
{
	char name[20];
	char sex;
	int id;
}Student;

void show_stu(void* ptr)
{
	Student* stu = ptr;
	printf("姓名:%s 性别:%c 学号:%d\n",stu->name,stu->sex,stu->id);
}

int cmp_id(const void* p1,const void* p2)
{
	const Student* s1 = p1,*s2 = p2;
	if(s1->id == s2->id) return 0;
	if(s1->id > s2->id) return 1;
	return -1;
}

int cmp_name(const void* p1,const void* p2)
{
	const Student* s1 = p1,*s2 = p2;
	return strcmp(s1->name,s2->name);
}

int main(int argc,const char* argv[])
{
	List* list = create_list();
	for(int i=0; i<10; i++)
	{
		Student* stu = malloc(sizeof(Student));
		sprintf(stu->name,"hehe%d",i);
		stu->sex = i%2?'w':'m';
		stu->id = 1000+i;
		add_head_list(list,stu);
	}
	show_list(list,show_stu);
	printf("-------------------------\n");
	Student s1 = {"hehe1",'w',1000};
	
	//del_value_list(list,&s1,cmp_id);
	//del_value_list(list,&s1,cmp_name);
	//show_list(list,show_stu);	
	printf("query: ");
	show_stu(query_list(list,&s1,cmp_id));
	Student* s2 = query_list(list,&s1,cmp_id);
	s2->id = 8888;
	show_list(list,show_stu);
	destroy_list(list);

}

数组与矩阵

  • 数组:存储空间连续、数据类型相同的表结构

  • 矩阵:带二维信息的数据,一般使用二维数组来存储矩阵

    • 稀疏矩阵:矩阵存储有效数据不多,绝大多数都是无效信息数据不需要存储(数量的多少没有特定的标准,全凭感觉)
    • 这些矩阵如果使用二维数组存储的话,会非常浪费存储空间,为了节约内存,可以考虑对矩阵进行压缩
    • 特殊矩阵:
      • 上三角矩阵
        • 压缩方法:用一维数组存储
        • 数组的长度:n*(n+1)/2
        • 对应关系:( j + 1 )* j / 2 + i ->对应的一维数组下标
        • 行列的关系:j >= i
      • 下三角矩阵
        • 压缩方法:用一维数组存储
        • 数组的长度:n*(n+1)/2
        • 对应关系:( i + 1 )* i / 2 + j ->对应的一维数组下标
        • 行列的关系:j <= i
      • 对称矩阵:沿着主对角线对称
        • 压缩方法:用一维数组存储,把它当作上三角或者下三角看待即可
        • 数组的长度:n*(n+1)/2
        • 对应关系:( j + 1 )* j / 2 + i 或者 ( i + 1 )* i / 2 + j ->对应的一维数组下标
        • 行列的关系:j >= i 或 j <= i
      • 对角矩阵(带状矩阵)
      • 【0】【1】【 】【 】
      • 【2】【3】【4】【 】
      • 【 】【5】【6】【7】
      • 【 】【 】【8】【9】
        • 压缩方法:用一维数组存储
        • 数组的长度:3n-2
        • 对应关系:2*i + j
        • 行列的关系:abs(i-j) <= 1
    • 无规律的稀疏矩阵:
      • 采用三元组方式进行压缩
      • 三元组:
        • 有三个数据项:行、列、值,构成一个整体,可以顺序存储,也可以链式存储
      • 注意:稀疏矩阵经过压缩后就丢失了随机访问的功能
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值