以下代码仅供参考,阅读时请先看NOTE,避免浪费时间
/** * @author: HCHO * @lastUpdateTime:2020/10/3 * @description: 双向链表的增删改查 */ /* NOTE: 所有代码仅供我个人学习使用,方法可能有误或者复杂化也有可能会有bug,读者请慎重操作 创建了一个头节点只是为了操作方便 在进行删除或增加的时候都应该考虑在最后一个节点操作时tail指针的改变所以引入双指针 上述情况造成的原因是我本人在建立链表时记录了尾节点的地址(为了逆序遍历链表)可能导致后续操作变得繁琐 为了方便这里的index变量都是大于等于1的值 个人用例如下: 5 1 2 3 4 5 */ #include<stdio.h> #include<stdlib.h> const int maxn=1e5+10; typedef long long ll; typedef struct node{ int Data; struct node *Pre; struct node *Next; }List; List *Head;//定义全局变量 List* buildList(int n){ List *Now,*Tmp; Head=(List*)malloc(sizeof(List)); //Head->Data=-1; Head->Pre=NULL; Head->Next=NULL; Now=Head; for(int i=0;i<n;i++){ Tmp=(List*)malloc(sizeof(List)); scanf("%d",&Tmp->Data); Tmp->Next=NULL; Tmp->Pre=NULL; Now->Next=Tmp; Tmp->Pre=Now; Now=Tmp; } return Now; } void printList(){//正序输出 List *tmp=Head->Next; while(tmp!=NULL){ printf("%d ",tmp->Data); tmp=tmp->Next; } printf("\n"); } void EX_printList(List *p){//逆序输出 List *tmp=p; while(tmp!=Head){ printf("%d ",tmp->Data); tmp=tmp->Pre; } printf("\n"); } void delete_item_from_List(List **tail,int num){ List *tmp=Head->Next; while(tmp!=NULL){ if(tmp->Data==num){ if(tmp->Next==NULL){//如果要删除的元素是最后一个,因为其Next指针为空所以要特判 *tail=(*tail)->Pre; tmp->Pre->Next=NULL; free(tmp); break; } tmp->Pre->Next=tmp->Next; tmp->Next->Pre=tmp->Pre; // tmp->Next->Pre=tmp->Pre; // tmp->Pre->Next=tmp->Next; free(tmp); break; } tmp=tmp->Next; } } void EX_delete_item_from_List(List **tail,int num){ List *tmp=*tail; if(tmp->Data==num){ *tail=(*tail)->Pre; tmp->Pre->Next=NULL; free(tmp); return; } while(tmp!=Head){ if(tmp->Data==num){ tmp->Pre->Next=tmp->Next; tmp->Next->Pre=tmp->Pre; // tmp->Next->Pre=tmp->Pre; // tmp->Pre->Next=tmp->Next; free(tmp); break; } tmp=tmp->Pre; } } void add_item_to_List(List **tail,int num,int index){ List *p=Head,*tmp; int f=1;//用来判断index是否越界 for(int i=1;i<index;i++){//找到index前一个节点 p=p->Next; if(p==NULL){ f=0; break; } } if(f==0){ printf("Error\n"); return; } tmp=(List*)malloc(sizeof(List)); tmp->Data=num; tmp->Pre=NULL; tmp->Next=NULL; if(p==*tail){ p->Next=tmp; tmp->Pre=p; *tail=(*tail)->Next; }else{ // p->Next->Pre=tmp; // tmp->Pre=p; // tmp->Next=p->Next; // p->Next=tmp; tmp->Pre=p; tmp->Next=p->Next; p->Next=tmp; tmp->Next->Pre=tmp; } } void modif_item_from_item(int num,int index){ List *p=Head; int f=1;//用来判断index是否越界 for(int i=0;i<index;i++){ p=p->Next; if(p==NULL){ f=0; break; } } if(f==0){ printf("Error\n"); return; }else{ p->Data=num; } } List* Search(int num){//查找num这个数字并返回其地址 List* p=Head; while(p!=NULL){ if(p->Data==num){ return p; } p=p->Next; } return NULL; } List* Search_item(int index){//查找第index元素并返回其地址 List *p=Head; for(int i=0;i<index;i++){ p=p->Next; if(p==NULL) return NULL; } return p; } void freeSpace(){ List *tmp; while(Head!=NULL){ tmp=Head; Head=Head->Next; free(tmp); } } int main(){ int n; scanf("%d",&n); List *tail=buildList(n); printList(); EX_printList(tail); printf("====================================\n"); // EX_delete_item_from_List(&tail,5);//删除最后一个节点的数据会影响tail指针,所以因进行传址 // EX_printList(tail); // delete_item_from_List(&tail,5); // printList(); // add_item_to_List(&tail,6,6); // printList(); // EX_printList(tail); // List *tmp=Search(5); // printf("*%d\n",tmp->Data); // List *tmp=Search_item(5); // if(tmp==NULL){ // printf("Error\n"); // }else{ // printf("*%d\n",tmp->Data); // } freeSpace(); system("pause"); return 0; }