数据结构单向循环表和双向表 02

今天学习了设计单向循环表和双向表,

创建一个动态单向循环链表,步骤如下:
1. 定义链表结点:数据域 + 指针域
2. 定义链表结构体:头结点指针
3. 初始化链表
4. 指定位置插入新数据 ( 头插法,中间插法 )
5. 删除指定位置数据
6. 获取链表长度
7. 依据数据查找所在链表位置
8. 返回第一个结点
9. 打印链表结点数据
10.释放链表
代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct node{
	int date;
	struct node *next;
}linke;

//初始化
linke *linke_init(){
	linke *p = (linke *)malloc(sizeof(linke));
	p->next = p;
	return p;
}

//插入
static void insert(linke *p, linke *new_p){
	new_p->next = p->next;
	p->next = new_p;
}

//插入
void linke_add(linke *p, int d){
	linke *head = p;
	linke *node = (linke *)malloc(sizeof(linke));
	node->date = d;
	while(p->next != head){
		p = p->next;
	}
	insert(p,node);
}

//删除
void linke_del(linke *p, int d){
	linke *head = p;
	linke *del = NULL;
	while(p->next != head){
		if(p->next->date == d){
			del = p->next;
			p->next = del->next;
			free(del);
			del = NULL;
			break;
		}
		p = p->next;
	}
}

//更新
void linke_update(linke *p, int old, int new){
	linke *head = p;
	while(p->next != head){
		if(p->next->date == old){
			p->next->date = new;
		}
		p = p->next;
	}
}

//查找
int linke_find(linke *p, int d){
	linke *head = p;
	int i = 0;
	while(p->next != head){
		if(p->next->date == d)
		{
			return i + 1;
		}
		i++;
		p = p->next;
	}
	return -1;
}

//打印
void linke_print(linke *p){
	linke *head = p;
	printf("链表:");
	while(p->next != head){
		p = p->next;
		printf("%d--",p->date);
	}
	printf("\n");
}

//释放
void linke_free(linke *p){
	linke *head = p;
	linke *fre = NULL;
	while(p->next != head){
		fre = p->next;
		p->next = fre->next;
		free(fre);
		fre = NULL;
		continue;
	}
	free(head);
	head = NULL;
}

int main(){
	int i;
	linke *head = linke_init();

	for(i = 0; i < 6; i++){
		linke_add(head,i);
	}
	linke_print(head);

	linke_del(head,3);
	linke_print(head);

	linke_update(head,2,999);
	linke_print(head);

	int num = 0;
	num = linke_find(head,4);
	printf("它在第%d位\n",num);

	linke_free(head);
	return 0;
}
双向表就是在 单链表 的的每个结点中,再设置一个指针域,也就是每个结点都有两个指针域,一个指向它的前驱结点,一个指向它的后继结点。
1. 指针域:用于指向当前节点的直接前驱节点;
2. 数据域:用于存储数据元素。
3. 指针域:用于指向当前节点的直接后继节点;
#include<string.h>
#include<stdio.h>
#include<stdlib.h>

typedef struct node{
	int date;
	struct node *after;
	struct node *befor;
}linke_doub;

linke_doub *linke(){
	linke_doub *p = (linke_doub *)malloc(sizeof(linke_doub));
	p->after = p->befor = NULL;
	return p;
}

void linke_d_add(linke_doub *p, int d){
	linke_doub *head = p;
	if(p->after == NULL){
		linke_doub *p_new = (linke_doub *)malloc(sizeof(linke_doub));
		p_new->date = d;
		p_new->after = head->after;
		head->after = p_new;
		p_new->befor = head;
	}
	else{
		linke_doub *p_new = (linke_doub *)malloc(sizeof(linke_doub));
		p_new->date = d;
		head->after->befor = p_new;
		p_new->befor = head;
		p_new->after = head->after;
		head->after = p_new;
	}
}

void linke_d_del(linke_doub *p, int d){
	linke_doub *head = p;
	while(head->after != NULL){
		head = head->after;
		if(head->date == d){
			head->after->befor = head->befor;
			head->befor->after = head->after;
			break;
		}
	}
	free(head);
	head = NULL;
}

void linke_d_update(linke_doub *p, int old, int new){
	linke_doub *head = p;
	while(head->after != NULL){
		head = head->after;
		if(head->date == old){
			head->date = new;
		}
	}
}

int linke_d_find(linke_doub *p, int d){
	linke_doub *head = p;
	int i = 1;
	while(p->after != NULL){
		head = head->after;
		if(head->date == d){
			return i;
		}
		i++;
	}
	return -1;
}

void linke_d_p(linke_doub *p){
	linke_doub *head = p;
	while(head->after != NULL){
		head = head->after;
		printf("%d->",head->date);
	}
	printf("\n");
	while(head->befor->befor != NULL){
		printf("<-%d",head->date);
		head = head->befor;
	}
	printf("<-%d\n",head->date);	
}

void linke_d_f(linke_doub *p){
	linke_doub *tmp;
	while(p->after != NULL)
	{
		tmp = p;
		p = p->after;
		free(tmp);
		tmp = NULL;
	}
	free(p);
	p = NULL;
}

int main(){
	linke_doub *p = linke();
	int i;
	for(i = 0; i < 6; i++){
		linke_d_add(p,i);
	}
	linke_d_p(p);

	linke_d_del(p,4);
	linke_d_p(p);
	
	linke_d_update(p,2,222);
	linke_d_p(p);
	
	int ret = linke_d_find(p,3);
	printf("它在第%d位\n",ret);

	linke_d_f(p);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简欧k

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值