双向链表(结构体再封装)

        双向链表相对于单链表来说 节点多了一个存放前节点地址的指针域。可以从前往后访问与从后往前访问,其余和单链表类似。

        不过在链表的删除和插入过程中要注意区分一些头尾节点和普通节点操作上的区别。

//循环链表(再封装形式)
#include <stdio.h>
#include <stdlib.h>
typedef struct _Node{
	int data;
	struct _Node* left;
	struct _Node* right;
}Node;

//再封装:描述一种结构的特点属性,抽象出来再封装
typedef struct _List{
	Node* firstNode;
	Node* lastNode;
	int size;
}List;
Node* createNode(int data){
	Node* newNode = (Node*)malloc(sizeof(Node));
	newNode->data = data;
	newNode->left = NULL;
	newNode->right = NULL;
	return newNode;
}

List* createList(){
	List* list = (List*)malloc((sizeof(List)));
	list->firstNode = NULL;
	list->lastNode = NULL;
	list->size = 0;
	return list;
}

void addNewNodeByHead(List* list,int data){
	Node* newNode = createNode(data);
	if (list->size == 0){
		list->firstNode = newNode;
		list->lastNode = newNode;

	}
	else{
		newNode->right = list->firstNode;
		list->firstNode->left = newNode;
		list->firstNode = newNode; 
	}
	list->size++;
}
void addNewNodeByTail(List* list, int data){
	Node* newNode = createNode(data);
	if (list->size == 0){
		list->firstNode = newNode;
		list->lastNode = newNode;

	}
	else{
		list->lastNode->right = newNode;
		newNode->left = list->lastNode;
		list->lastNode = newNode;
	}
	list->size++;
}
void printList(List* list){
	if (list->firstNode == NULL){
		printf("链表为空,无法输出。\n");
	}
	else{
		Node* pMoveNode = list->firstNode;
		while (pMoveNode !=NULL){
			printf("%d ", pMoveNode->data);
			pMoveNode = pMoveNode->right;
		}
	}
	printf("\n");
}
void addNodeByPos(List* list, int posData, int data){
	if (list->firstNode == NULL){
		printf("链表为空,找不到指定位置插入!\n");
	}
	else{
		Node* posNode = createNode(data);
		Node*pMoveNode = list->firstNode;
		while (pMoveNode != NULL&&pMoveNode->data != posData){
			pMoveNode = pMoveNode->right;
		}
		if (pMoveNode == NULL){
			printf("链表中没有指定位置!\n");
		}
		else if (pMoveNode == list->firstNode){
			addNewNodeByHead(list, data);
		}
		else{
			posNode->left = pMoveNode->left;
			pMoveNode->left = posNode;
			posNode->left->right = posNode;
			posNode->right = pMoveNode;		
		}
		list->size++;
	}
}
void deleteNodeByHead(List* list){
	if (list->firstNode == NULL){
		printf("链表中没有节点,无法删除!\n");
	}
	else{
		Node* pMoveNode = list->firstNode;
		list->firstNode->right->left = NULL;
		list->firstNode = list->firstNode->right;
		free(pMoveNode);
		pMoveNode = NULL;
		list->size--;
	}
}
void deleteNodeByTail(List* list){
	if (list->firstNode == NULL){
		printf("链表中没有节点,无法删除!\n");
	}
	else{
		Node* pMoveNode = list->lastNode;
		list->lastNode->left->right=NULL;
		list->lastNode = list->lastNode->left;
		free(pMoveNode);
		pMoveNode = NULL;
	}
}
void deleteNodeByPos(List* list, int posData){
	if (list->firstNode == NULL){
		printf("链表中没有节点,无法删除!\n");
	}
	else{
		Node* posNode = list->firstNode;
		while (posNode != NULL&&posNode->data != posData){
			posNode = posNode->right;
		}
		if (posNode == NULL){
			printf("链表中没有该指定节点,无法删除!\n");
		}
		else if (posNode == list->firstNode){
			deleteNodeByHead(list);
		}
		else if (posNode == list->lastNode){
			deleteNodeByTail(list);
		}
		else {
			posNode->right->left = posNode->left;
			posNode->left->right = posNode->right;
			free(posNode);
			posNode = NULL;
		}
		list->size--;
	}
}
int main(){
	List* list = createList();
	addNewNodeByHead(list, 10);
	addNewNodeByHead(list, 20);
	addNewNodeByHead(list, 30);
	addNewNodeByHead(list, 40);
	addNewNodeByTail(list, -10);
	printList(list);
	addNodeByPos(list, -10, 70);
	deleteNodeByHead(list);
	printList(list);
	deleteNodeByTail(list);
	printList(list);
	deleteNodeByPos(list, 70);
	printList(list);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值