简单的双向链表

什么是双向链表?

之前接触的链表都是有一个指针域指向后继元素,现在还有另一种做法,就是在节点内额外加多一个指针域,一个指针域用来指向他的上一个节点地址,另一个指针域用来指向下一个节点的地址,这样的链表我们称之为双向链表。

首先,创建结构体和头文件等
typedef struct Link
{
	int data;
	struct Link *up;
	struct Link *next;
}link;

link * insertLine(link * head,int newElem,int add);
link * editLine(link * head,int newElem,int edit);
link * delLine(link * head,int delElem);
复制代码
初始化链表
link *initLink(int n)
{
	link *head = (link*)malloc(sizeof(link));//申请空间定义头节点
	int i;
	head->data = 1;
	head->up = NULL;
	head->next = NULL;
	link *tempLink = head;
	
	for (i=2; i<n; i++) {
		link *a = (link*)malloc(sizeof(link));//申请空间
		a->up = tempLink;//指针域指向上一个节点
		a->data = i;
		a->next = NULL;
		
		tempLink->next = a;//指针域指向下一个节点
		tempLink->up = tempLink;
		tempLink = a;
	}
	
	return head;
}
复制代码
增加一个元素
link * insertLine(link * head,int newElem,int add)
{
	link *tempLink = (link*)malloc(sizeof(link));//申请空间,插入一个元素
	tempLink->data = newElem;
	tempLink->next = NULL;
	tempLink->up = NULL;
	
	if (add == 1) {//如果插入的地方是头部
		tempLink->next = head;//它的后指针域指向head
		head->up = tempLink;//它的前指针域指向它自己
		head = tempLink;//将指针域再次移到头节点
	} else {
		int i;
		link *body = head;
		for (i=1;i<add-1;i++){
			body = body->next;//找到要插入结点的前一个结点
		}
		if (body->next==NULL) {//如果插入的地方是最后一个位置
			body->next = tempLink;
			tempLink->up = body;
		} else {
			
			body->next->up = tempLink;//更改插入位置的下一个节点的前趋针域
			tempLink->next = body->next;//将自己节点的后指针域指向 未插入前自己上一个节点的后继指针
			
			body->next = tempLink;//更改上一个节点的后继指针地址
			tempLink->up = body;//将自己节点的前趋指针 指向上一个节点的地址
		}
	}
	return 	head;
}
复制代码
删除一个元素
link * delLine(link * head,int delElem)
{
	link *tempLink = head;
	while (tempLink->next) {
		
		if (tempLink->data == delElem) {//找到要删除的地址
			tempLink->up->next = tempLink->next;//更改它上一个的后继指针地址
			tempLink->next->up = tempLink->up;//更改它下一个节点的前趋指针地址
			free(tempLink);//释放内存
			return head;
		}
		tempLink = tempLink->next;
	}
}
复制代码
打印链表
void showLink(link *head)
{
    link * temp=head;
    while (temp) {
        if (temp->next==NULL) {
            printf("%d\n",temp->data);
        }else{
            printf("%d->",temp->data);
        }
        temp=temp->next;
    }
}
复制代码
修改一个元素
link * editLine(link * head,int newElem,int edit)
{
	link *tempLink = head;
	int i;
	for (i=1;i<edit;i++) {
	    tempLink = tempLink->next;
	}
	tempLink->data = newElem;
	return head;
}
复制代码
运行
int main()
{
	int n;
	n = 10;
	link *head = initLink(n);
	printf("初始化链表\n");
	showLink(head);
	
	printf("添加\n");
	
	insertLine(head,4,2);
	showLink(head);
	
	printf("修改\n");
	
	editLine(head,5,2);
	showLink(head);
	
	printf("删除\n");
	delLine(head,5);
	showLink(head);
}
复制代码
运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值