数据结构C语言实现单链表

c语言实现单链表的插入、删除、查找和遍历功能,逆序功能稍等

链表最难的就是指针的操作,所以要多画一下,然后对照图写代码实现功能,才能增进对链表的理解

原理如图:

代码实现如下: 

/*单链表*/
#include <stdio.h>
#include <stdlib.h>
typedef int T;
typedef struct node{	/* 1 节点类型定义 */
	T data;
	struct node* next;
}Node;
#define SIZE sizeof(Node)
/*3 添加节点到链表末尾*/
void add(Node* h,T d){/*头节点地址,新节点数据*/
	if(h == NULL){
		printf("空链表,添加失败!\n");
		return;
	}
	Node* p = h;	//p指向链表头
	//3.1 创建新节点并赋值
	Node* pn = malloc(SIZE);
	pn->data = d;
	pn->next = NULL;
	//3.2 找到链表的尾节点
	while(1){
		if(p->next == NULL)
			break;
		p = p->next;
	}
	//while(p) p = p->next;			不能
	//while(p->next) p = p->next;	可以
	//while(p = p->next);			
	//3.3 把新节点连接到尾节点
	p->next = pn;
	printf("add success!\n");
}
/*4。遍历链表*/
void travel(Node* h){
	//4.1 保存头节点地址
	Node* p = h;
	//4.2 循环后挪
	printf("list:");
	while(p->next != NULL){
		p = p->next;//先挪后打印 p->next!=NULL    头节点不打印
	//4.3 打印当前节点数据
		printf("%d ",p->data);
		//p = p->next;//先打印后挪 p != NULL   头节点打印
	}
	printf("\n");
}
/*5 插入节点到指定位置*/
void insert(Node* h,int n,T d){
	int i;
	//5.1 p指向要插入节点的前一个节点
	Node* p = h;
	for(i = 0;i < n-1;i++){
		p = p->next;
		if(p == NULL){
			printf("没有位置插入,insert error!\n");
			return;
		}
	}
	if(p->next == NULL){
		add(h,d);
		return;
	}
	//5.2 创建新节点
	Node* pn = malloc(SIZE);
	pn->data = d;
	//pn->next = NULL;
	//5.3 新节点连接p->next节点
	pn->next = p->next;	
	//5.4 p->next指向新节点
	p->next = pn;
}
/*6 返回某个位置的节点地址*/
Node* getpos(Node* h,int n){
	int i;
	Node* p = h;
	for(i=0;i<n;i++){
		if(p == NULL){
			printf("getpos error!\n");
			return NULL;
		}
		p = p->next;
	}
	return p;
}
/*7 调用getpos的insert*/
void g_insert(Node* h,int n,T d){
	Node* p = getpos(h,n-1);
	if(p == NULL)
		return;
	if(p->next == NULL){
		add(h,d);
		return;
	}
	Node* pn = malloc(SIZE);
	pn->data = d;
	pn->next = p->next;	
	p->next = pn;
}
/*8 修改某个位置上的数据为新的数据*/
void set(Node* h,int n,T d){
	//8.1 p指向要修改的节点
	Node* p = getpos(h,n);
	if(p == NULL){
		printf("找不到节点!\n");
		return;
	}
	//8.2 修改数据
	p->data = d;
}
/*9 删除某个节点*/
void delpos(Node* h,int n){
	//找到要删除的节点的前一个节点
	Node* pb = getpos(h,n-1);
	if(pb == NULL){
		printf("找不到节点!\n");
		return;
	}
	//找到要删除的节点
	Node* pd = pb->next;
	if(pd == NULL){
		printf("找不到节点!\n");
		return;
	}
	//判断要删除的节点是否是尾节点
	if(pd->next == NULL){
		pb->next = NULL;
		printf("删除尾节点!\n");
		free(pd);
		pd = NULL;
		return;
	}
	//要删除的节点不是尾节点
	pb->next = pd->next;//pb->next = pb->next->next;
	pd->next = NULL;
	free(pd);
	pd = NULL;
	return;
}


int main(){
	/*2 创建头节点*/
	Node* head = NULL;	//2.1 定义指针
	head = malloc(SIZE);//2.2 分配内存
	head->data = 0;		//2.3 赋值
	head->next = NULL;

	travel(head);

	add(head,8);
	add(head,7);
	add(head,99);
	travel(head);
	insert(head,3,666);
	travel(head);
	g_insert(head,4,444);
	travel(head);
	set(head,4,888);
	travel(head);
	delpos(head,3);
	travel(head);
	delpos(head,4);
	travel(head);
	return 0;
}

还有注意结构体对于节点创建 ,节点内存空间的开辟,还有就是对于节点的释放都是要注意的。

发布了37 篇原创文章 · 获赞 16 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/double_lee3/article/details/87806583