双向链表相对于单链表来说 节点多了一个存放前节点地址的指针域。可以从前往后访问与从后往前访问,其余和单链表类似。
不过在链表的删除和插入过程中要注意区分一些头尾节点和普通节点操作上的区别。
//循环链表(再封装形式)
#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;
}