链表的各种操作

来源:互联网 发布:mysql怎么删除数据 编辑:程序博客网 时间:2024/05/01 18:13
//基本上都是照着视频打的。。。//链表的各种操作方法#include <stdio.h>#include <stdlib.h>#include <malloc.h>struct Node {  int nid;  char msg[20];  struct Node *next;};/* * 操作1:初始化链表 *  参数pHead为链表的头文件,该方法用于将头指针指向NULL, 代表该链表为一个空的链表, *  从而实现链表的初始化操作*/void initLinkList(struct Node **pHead){  *pHead = NULL;  printf("操作:>链表初始化成功!\n");}/* *操作2:创建链表结构 *参数pHead为链表的头指针,将该参数进行输入操作后返回即实现了链表的操作 *  */ struct Node * createLinkList(struct Node *pHead) {   struct  Node *p1, *p2;  int size = 0;  char c;  //操作符号    printf("提示:>开始创建链表结构...");  do{ size = size + 1; //将size的值+1 p1 = (struct Node *)malloc(sizeof(struct Node));//p1申请内存空间 printf("编号:>"); scanf("%d", &p1->nid); printf("内容 :>"); scanf("%s", p1->msg); //判断该节点是否为链表中的第一个节点 if(size == 1)  pHead = p1; else p2->next = p1; p2 = p1; //重要:让p2指针指向p1新创建的节点上 printf("继续(y/n)? :> "); getchar(); scanf("%c", &c);     }while(c == 'y' || c == 'Y');  p2->next = NULL; //将最后一个节点的*next指向NULL  printf("操作:>链表创建完毕!\n");  return pHead; //将头指针返回  }/* *操作3:判断链表是否为空 * 参数pHead判断是否指向NULL */  int isEmptyLinkList(struct Node *pHead) {   return pHead == NULL ? 1:0;  } /*  *操作4:输出链表结构   *参数pHead,使用while循环格式化输出链表结构  */void printLinkList(struct Node *pHead){    struct Node *p;    if(!isEmptyLinkList(pHead)){       p = pHead; //将p指针指向pHead,避免直接操作原始pHead       printf("## 链表输出:");       do {          printf("[%s]", p->msg);          if (p->next != NULL){           printf(" ->");          }          p = p->next;         }while(p != NULL);       printf("\n");      }else{      printf("提示:>该链表为空!\n");     }}/* *操作5:统计节点的个数 * 参数pHead,通过循环便利节点累加统计节点的个数 */ int getLinkListNodeCount(struct Node *pHead) {  struct Node *pTmp;  pTmp = pHead;  int count = 1;  while (pTmp->next != NULL){      count += 1;      pTmp = pTmp->next;  }  return count;}/* *操作6:链表的检索 *参数 pHead, position *pHead为链表指针, position为检索的链表节点编号 */ struct Node *  seekLinkList(struct Node *pHead, int position) {   struct Node *pTmp;   int i, nodeCount = getLinkListNodeCount(pHead);   if(position > nodeCount || position <= 0){     printf("错误:>您所指定的节点编号不存在! \n");  } else {     pTmp = pHead;     for (i=0; i<position-1;i++){      pTmp = pTmp->next;     }     return pTmp;  } }/* *操作7:输出指定的链表中的节点数据 *参数结构体指针,输出指针所指向的数据 */ void printNodeData(struct Node *p) {  printf("节点信息: ");  printf("[%d, %s]\n", p->nid, p->msg); } /*  * 操作8:删除链表指定位置的节点  * 参数position, 获取删除节点的位置,通过seekLinkList方法获取该位置的指针,通过position-1/  *   position+1 获取删除节点前置和后置节点指针,便于后续操作  */int deleteNodeByPosition(struct Node **p, struct Node *pHead, int position){   struct Node *pDelete, *pPrev, *pNext;   int nodeCount = getLinkListNodeCount(pHead);   if (position > nodeCount || position <= 0){      printf("错误:>您输入的节点位置不存在 !\n");      return 0;      }else{      pDelete = seekLinkList(pHead, position); //获取待删除的节点指针      if(pDelete == pHead){ //判断该节点是否为第一个节点         printf("操作:>正在删除第一个节点...\n");         pNext = seekLinkList(pHead, (position+1));         *p = pNext;       }else if(pDelete->next == NULL){ //判断该节点是否为最后一个节点         printf("操作:>正在删除最后一个节点.....\n");         pPrev = seekLinkList(pHead, (position-1));          pPrev->next = NULL;           }else{         printf("操作:> 正在删除链表中的节点.....\n");         pPrev = seekLinkList(pHead, (position-1));         pNext = seekLinkList(pHead, (position+1));         pPrev->next = pNext;  //前置节点的*next指针指向后置节点         }      pDelete = NULL;  //当前删除的指针置空      return 1;       }}  /* *操作9:实现对链表节点的添加操作 *参数:**p, *pHead, position, flag * 首先判断插入位置是否正确,其次获取插入位置的节点指针, 获取*pPrev, *pNext */ int insertLinkListNode(struct Node **p, struct Node *pHead, int position, int flag) {    struct Node *pThis, *pPrev, *pNext, *pInsert;    int nodeCount = getLinkListNodeCount(pHead);    if(position > nodeCount ||position <= 0){      printf("错误:插入节点的位置数据不存在");      return 0;    }else{       //首先开辟一个节点的内存空间       pInsert = (struct Node *)malloc(sizeof (struct Node));       //为该节点赋值       printf("请输入新的节点信息:\n");       printf("编号:>");       scanf("%d", &pInsert->nid);       printf("内容:>");       scanf("%s", pInsert->msg);       pThis = seekLinkList(pHead, position);       if(pThis == pHead){          if(!flag){            printf("操作:>向第一个节点[前]插入新的节点数据.....\n");            *p = pInsert;  //将头指针指向新添加的节点            pInsert->next = pThis;  // 将新添加的节点*next1指向原先的第一个节点                   }else{             printf("操作:>向第一个节点[后]插入新的节点数据.....\n");             pNext = seekLinkList(pHead, (position + 1));             pThis -> next = pInsert;//             pInsert->next = pNext;                        }          }else if(pThis->next == NULL){//链表中的最后一个节点后追加一个节点             if(!flag){              printf("操作:>向最后一个节点[前]插入新的节点数据....\n");              pPrev = seekLinkList(pHead,(position - 1));              pPrev->next = pInsert;              pInsert->next = pThis;             }else{             printf("操作:>向第最后一个节点[后]插入新的数据......\n");             pThis->next = pInsert;             pInsert->next = NULL;                         }          }else{//链表中的中间节点             if(!flag){               printf("操作:>向中间节点[前]插入新的节点数据....\n");               pPrev = seekLinkList(pHead, (position - 1));      pPrev->next = pInsert;      pInsert->next = pThis;             }else{              printf("操作:>向中间节点[后]插入新的节点数据......\n");              pNext = seekLinkList(pHead, (position + 1));              pThis->next = pInsert;              pInsert->next = pNext;             }                    }              return 1;    }  } int main(void){  struct Node *pHead, *pTmp;  int choise,position,flag,dist;  char selected;  do{  system("clear");  printf("\n\n===================================\n");  printf("\t工程实践:链表的操作\n");  printf("----------------------------------------\n");  printf("     功能菜单:\n");  printf("\t(1) 初始化链表\n");  printf("\t(2) 创建链表结构\n");  printf("\t(3) 输出链表结构\n");  printf("\t(4) 通过位置检索链表节点\n");  printf("\t(5) 删除链表节点\n");  printf("\t(6) 插入链表节点\n");  printf("\t(7) 退出 \n");  printf("\n========================================\n");  printf("请选择功能:");  scanf("%d", &choise);    switch (choise){   case 1:    initLinkList(&pHead); break;//初始化链表结构      case 2:    pHead = createLinkList(pHead); break;//创建链表结构   case 3:    printLinkList(pHead);  break;//输出链表结构   case 4:    printf("请输入需要检索的节点位置(1-%d): >", getLinkListNodeCount(pHead));    scanf("%d", &position);    pTmp = seekLinkList(pHead, position); //检索链表节点    if(pTmp != NULL){      printNodeData(pTmp);//输出节点信息    }   break;   case 5:   printf("请输入需要删除的节点位置(1-%d):>",getLinkListNodeCount(pHead));   scanf("%d", &position);   if(deleteNodeByPosition(&pHead, pHead, position)){     printf("操作:> 第%dg个节点删除成功!\n",position);     printLinkList(pHead);  break;//输出链表结构   }else{     printf("操作:>第%d个节点删除失败!\n",position);   }   break;   case 6:     printf("请输入插入节点的位置(1-%d):>", getLinkListNodeCount(pHead));     scanf("%d", &position);     printf("确定插入位置[0. 前置插入  1.后置插入]:>");     scanf("%d", &flag);      if(insertLinkListNode(&pHead, pHead, position, flag)){       printf("操作:> 节点插入成功!\n");       printLinkList(pHead);  break;//输出链表结构      }else{        printf("操作:> 节点插入失败!\n");      }   break;   case 7:   exit(0);break;   default:break;  }    printf("\n继续操作?(y/n):> ");  getchar();  scanf("%c", &selected);  }while(selected == 'y' || selected == 'Y');  return 0;}  

0 0