链表详解(单向)

141 阅读2分钟

单向链表

头文件

#include<stdio.h>
#include<stdlib.h>

首先定义一个结构体,里面是链表每个节点的指针和值

typedef struct node
{
	int value;
	struct node* next;
}Node;

函数

add函数

此函数为给链表传值

void add(int data, Node** Phead) {		//因为此函数里面要改head,故传进去指针的指针
                                                  //这里的Phead意思为head的地址
        Node* p = (Node*)malloc(sizeof(Node));          //定义Node类型的指针,并分配地址     
	p->value = data;                                //放入数据
	p->next = NULL;                            
	//以上已经处理好了我们所要添加的节点
        //接下来我们要把它放在链表的末尾
        //
	Node* last = *Phead;                        //先让指针last指向head
	if (last != NULL) {				//当这个链表不为空的时候
	        /*让last指向最后一个节点*/
		while (last->next != NULL) {
			last = last->next;
		}
		/*当last->next为NULL的时候,连接上我们所要添加的结点*/
		last->next = p;
	}
	else {					  //当链表是空的,就把节点连接	
		*Phead = p;                      //这里改变了head的值,
                                                //故这个函数需要放入指针的指针,这样才能更改head的值
	}
}

del函数

此函数为删除链表中某个值

void del(int data, Node** Phead) {                //同上,传入指向head的指针
        //这里定义两个指针,q在后,p在前,遍历链表
        //定义两个的目的是便于把链表重新连接
	Node* q, * p;
	for (p = *Phead, q = NULL; p != NULL; q = p, p = p->next) {      //遍历整个链表
		if (p->value == data) {                     //如果p指向了要删除的数据
			if (q) {			   //并且后面的q不为空
                            q->next = p->next;           //跳过所要删除的,进行连接
			}
			else {		             //当q是空的时候
                                                     //意味着链表第一个节点就是要删除的
                                                        
				*Phead = p->next;
			}
                        free(p);                     //释放所要删除的链表内存(p所指向的那个)
			break;
		}

	}
}

delall函数

此函数为删除整个链表

void delall(Node** head) {
        Node* p = NULL, * q;
	for (p = *head; p; p = q) {
		q = p->next;			
		free(p);
	}
}

主函数

int main()
{
	Node* head = NULL;
	int data;
        //读入数据
	do {
		scanf("%d", &data);
		if (data != -1) {
			add(data, &head);

		}
	} while (num != -1);
        
        //遍历这个链表
	Node* p;
	for (p = head; p != NULL; p = p->next) {
		printf("%d\t", p->value);
	}
	printf("\n");

	//删除某个节点
	int data2;
	scanf("%d", &data2);
	del(data2, &head);
        
        //遍历输入整个链表
	for (p = head; p != NULL; p = p->next) {
		printf("%d\t", p->value);
	}
	printf("\n");

	//删除整个链表
	delall(&head);


	return 0;

}