数据结构 --手撕链表

链表是一种应用的很广泛的数据结构,在内存中不连续的分布,下面将介绍链表的增、删、改、查。

链表的每一个节点都是一个结构体,val是这个节点的值,next是下一个节点的地址

typedef struct List{
	int val;
	struct List *next;
}List;

链表的插入,root是链表的头结点,value是要插入的值,默认插入到链表的尾端

List * listInsert(List *root,int value){
	if(root == NULL){
    	root = (List*)malloc(sizeof(List));
    	root->val = value;
    	root->next = NULL;
    	return root;
	}
	struct List *l = root;
	while(l->next != NULL){
    	l = l->next;
	}
	struct List* p = (List*)malloc(sizeof(List));
	p->val = value;
	p->next = NULL;
	l->next = p;
	return root;
}

当root是空的时候,位root分配内存,赋值,否则,找到当前链表的最后一个节点,赋值,返回

链表的插入,这个可以指定插入的位置(从0开始),i就是要插入的位置

List* listInsert(List *root,int value,int i){
struct List* p = root;
	if(i == 0){
    	struct List* l = (List*)malloc(sizeof(List));
   		l->val = value;
    	l->next = root;
    	return l;
	}
	--i;
	while((p->next != NULL) && (i != 0)){
    	--i;
    	p = p->next;
	}
	if(p->next == NULL) return root;
	struct List* l = (List*)malloc(sizeof(List));
	l->val = value;
	l->next = p->next;
	p->next = l;
	return root;
}

当i等于0的时候,就是要插入到头节点,否则,通过i找到要插入的节点,分配内存,将节点插入即可,
注意,当链表节点的总数小于i的时候,不插入,直接返回

链表的删除,root是链表头节点,i是要删除的节点的位置

List* listDelete(List* root,int i){
	struct List *p = root;
	if(i==0){
    	if(root == NULL)
        return root;
    	else return root->next;
	}
	--i;
	while((p->next != NULL) && (i != 0)){
    	--i;
    	p = p->next;
	}
	if(p->next == NULL) return root;
	struct List* l = p->next;
	p->next = p->next->next;
	free(l);
	return root;
}

参照上面链表的插入,找到要删除的节点,删除,释放该节点的内存

链表的节点值的改变,将第i个节点的值改成val

List* listChange(List* root,int val,int i){
	struct List *p = root;
	while((p != NULL) && (i != 0)){
   		--i;
    	p = p->next;
	}
	if(p == NULL) return root;
	p->val = val;
	return root;
}

链表的查找,找到值位val的节点,返回节点的地址

List* listFind(List* root,int val){
	List* p = root;
	while(p != NULL){
    	if(p->val == val)
        	return p;
    	p = p->next;
	}
	return NULL;
}

链表的打印,遍历所有节点,打印节点的值

void listPrint(List *root){
	struct List* p = root;
	while(p != NULL){
    	printf("%d ",p->val);
    	p = p->next;
	}
	printf("\n");
	return ;
}

测试函数

int main() {
	List *head = NULL;
	for(int i=0;i<6;++i)
    	head = listInsert(head,i);
	listPrint(head);

	head = listInsert(head,6,1);
	listPrint(head);

	head = listDelete(head,0);
	listPrint(head);

	head = listChange(head,10,4);
	listPrint(head);

	List* p = listFind(head,3);
    printf("%d\n",p->val);

	return 0;
}

测试结果,结果正确

0 1 2 3 4 5
0 6 1 2 3 4 5
6 1 2 3 4 5
6 1 2 3 10 5
3

所需头文件

#include 
#include 

这是我个人运营的公众号[工程师修炼手册],介绍C/C++、Python、嵌入式、操作系统、数据结构与算法、计算机网络和Linux等相关的知识。欢迎关注,一起学习,一起进步!
数据结构 --手撕链表_第1张图片

你可能感兴趣的:(c++,数据结构,链表)