0
点赞
收藏
分享

微信扫一扫

(数据结构)利用 C语言实现双向链表 —— 2022/3/17

双向链表

—— 头文件

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

结构体声明双向链表节点

// 声明节点结构
typedef struct two_way_linked_list{
	struct two_way_linked_list *prior;
	int data;
	struct two_way_linked_list *next;
} LinkList; 

构造创建双向链表的函数

// 创建双向链表的函数 
LinkList *initLink(int n){
	// 创建一个首元节点,链表的头指针为 head
    LinkList *head = (LinkList*)malloc(sizeof(LinkList));
    // 对节点进行初始化
    head->prior = NULL;
    head->next = NULL;
    scanf("%d", &head->data);
    // 声明一个指向首元节点的指针,方便后期向链表中添加新创建的节点
    LinkList *list = head;
    for(int i = 2; i <= n; i++) {
        // 创建新的节点并初始化
        LinkList *body = (LinkList*)malloc(sizeof(LinkList));
        body->prior = NULL;
        body->next = NULL;
        scanf("%d", &body->data);
        // 新节点与链表最后一个节点建立关系
        list->next = body;
        body->prior = list;
        // list永远指向链表中最后一个节点
        list = list->next;
    }
    // 返回新创建的链表
    return head;
}

构造展示双向链表的函数

// 展示双向链表元素的函数 
void display(LinkList *head){
	LinkList *temp = head;
	while(temp){
		if(temp->next != NULL){
			printf("%d <-> ", temp->data);
		}else{
			printf("%d\n", temp->data);
		}
		temp = temp->next;
	}
}

构造插入双向链表元素的函数

// 插入双向链表元素的函数 
LinkList *insertLink(LinkList *head, int data, int position){
	// 新建数据域为 data的节点 
	LinkList *temp = (LinkList*)malloc(sizeof(LinkList));
	temp->data = data;
	temp->next = NULL;
	temp->prior = NULL;
	// 若插入到链表头
	if (position == 1){
		temp->next = head;
		head->prior = temp;
		head = temp;
	}else{
		LinkList *body = head;
		// 找到插入位置的前一节点
		for(int i = 1; i < position-1; i++){
			body = body->next;
		} 
		// 表示插入双向链表尾部 
		if(body->next == NULL){
			body->next = temp;
			temp->prior = body; 
		}else{
			body->next->prior = temp;
			temp->next = body->next;
			body->next = temp;
			temp->prior = body;
		}
	}
	return head;
}

构造删除双向链表元素的函数

// 删除双向链表元素的函数
LinkList *delLink(LinkList *head, int data){
	LinkList *temp = head;
	// 删除头节点 
	if(temp->data == data){
		head = temp->next;
		free(temp);
		return head;
	}
	// 遍历符合要求的节点
	while (temp) {
        // 删除尾节点 
        if (temp->data == data && temp->next == NULL) {
			temp->prior->next = NULL;
			free(temp);
			return head;
        }else if(temp->data == data){
        	temp->prior->next = temp->next;
            temp->next->prior = temp->prior;
            free(temp);
            return head;
		}
        temp = temp->next;
    }
    printf("链表中无该数据元素");
    return head;	
} 

构造查找双向链表元素的函数

// 查找双向链表元素的函数
int selectElem(LinkList *head, int elem){
	LinkList *temp = head;
	int index = 1;
	while(temp->next != NULL){
		if(temp->data == elem){
			return index;
		}
		temp = temp->next;
		index++;
	}
	// 查找失败 
	return -1;
} 

构造更新双向链表元素的函数

// 更新双向链表元素的函数
LinkList *updateElem(LinkList *head, int elem, int newelem){
	int position = selectElem(head, elem); 
	LinkList *temp = head; 
	for (int i = 1; i < position; i++){
		temp = temp->next;
	} 
	temp->data = newelem;
	return head;
} 

—— 主函数

int main(void){
    LinkList *head = initLink(5);
    display(head);  // 1 <-> 2 <-> 3 <-> 4 <-> 5
    
    // 显示双链表的优点
    printf("链表中第3个节点的直接前驱的数据域:%d\n",head->next->next->prior->data);
    // output: 链表中第3个节点的直接前驱的数据域:2
    
    LinkList *newhead = insertLink(head, 7, 6); 
    display(newhead);  // 1 <-> 2 <-> 3 <-> 4 <-> 5 <-> 7
    
    LinkList *newhead_ = delLink(newhead, 7);
	display(newhead_);  // 1 <-> 2 <-> 3 <-> 4 <-> 5
	
	printf("元素4在双向链表中的位置为:%d\n", selectElem(newhead_, 4)); 
	// output: 元素4在双向链表中的位置为:4	
	
	LinkList *newhead__ = updateElem(newhead_, 2, 100);
	display(newhead__);  // 1 <-> 100 <-> 3 <-> 4 <-> 5
	return 0;
}
举报

相关推荐

0 条评论