模拟实现链表

该链表实现的功能:
1.指定位置之前插入元素
2.打印链表
3.删除指定元素
4.删除所有出现的指定元素
5.查找指定元素
6.对链表进行冒泡排序
7.头插
8.头删
9.尾插
10.尾删
11.销毁链表
下面进行分布详解:
 pLinkNode BuyNode(DataType x) // 为新增节点开辟空间,并赋值
因为新增节点很多地方都用,所以将新增节点,封装成一个函数
注意:对开辟空间是否成功要做判断。
 1 pLinkNode BuyNode(DataType x) //新增节点开辟空间
 2 {
 3      pLinkNode  newNode = (pLinkNode)malloc(sizeof(LinkNode));
 4      if (newNode == NULL)
 5      {
 6           printf("out of memory\n");
 7           exit(EXIT_FAILURE);
 8      }
 9      newNode->data = x;
10      newNode->next = NULL;
11      return newNode;
12 }
pLinkNode Find(pLinkList pList, DataType x)  
公用的查找函数,
返回找到元素的地址,
未找到返回NULL
 1 pLinkNode Find(pLinkList pList, DataType x) //公用的查找函数
 2 {
 3      assert(pList);
 4      pLinkNode cur = pList->phead;
 5      while (cur!=NULL)
 6      {
 7           if (cur->data == x)
 8           {
 9               return cur;
10           }
11           cur = cur->next;
12      }
13      return NULL;
14 }

 

void Insert(pLinkList pList,pLinkNode pos,DataType x)
将指定元素插入到指定位置
分为两种情况
(1):当链表只有一个元素时进行头插
(2):链中有多个元素
例如: 将2插入3之前表
 
void Remove(pLinkList pList,DataType x)
只删除第一个匹配到的元素。
三种情况:
1.链表只有一个元素,进行头删
2.删除的是链表最后一个元素,进行尾删
3.删除的是中间节点
完整代码:
LinkList.h
 1 #ifndef _LINK_LIST_
 2 #define _LINK_LIST_
 3 #define _CRT_SECURE_NO_WARNINGS 1
 4 #include<stdio.h>
 5 #include<stdlib.h>
 6 #include<assert.h>
 7 enum Select //j将所有选项用枚举列出来
 8 {
 9      EXIT,
10      INSERT, //指定位置之前插入
11      PRINT, //打印
12      REMOVE, //删除指定元素
13      REMOVEALL,//删除所有出现的元素
14      SEARCH,  //查找指定元素
15      SORT,  // 排序
16      PUSHF, //头插
17      PUSHB,//尾插
18      POPF,  //头删
19      POPB, //尾删
20      DOSTROY, //销毁链表
21      EASER //删除指定位置的元素
22 };
23 typedef int DataType;
24 typedef struct LinkNode  //节点
25 {
26      DataType data;
27      struct LinkNode* next;
28 }LinkNode, *pLinkNode;
29 typedef struct LinkList //将头指针单独封装在一个结构体中
30 {
31      LinkNode* phead;
32 }LinkList, *pLinkList;
33 void Init(pLinkList pList);//初始化链表
34 void PrintList(pLinkList pList);//打印链表
35 void DestroyList(pLinkList pList);//销毁链表
36 void PushFront(pLinkList pList, DataType x);//头插
37 void PushBack(pLinkList pList, DataType x);//尾插
38 void PopFront(pLinkList pList);   //头删
39 void PopBack(pLinkList pList);//尾删
40 void Insert(pLinkList pList, pLinkNode Pos, DataType x);//指定位置之前插入
41 pLinkNode Find(pLinkList pList, DataType x); //公用的查找函数
42 void Search(pLinkList pList, DataType x);//查找指定元素
43 void Exit(pLinkList pList);
44 void Remove(pLinkList pList, DataType x); //删除指定元素
45 void RemoveALL(pLinkList pList, DataType x); //删除所有出现的元素
46 void Erase(pLinkList pList, pLinkNode pos);//删除指定位置的元素
47 void BubbleSort(pLinkList pList);//对链表进行冒泡排序
48 #endif //_LINK_LIST_

 LinkList.c

#include"LinkList.h"
pLinkNode BuyNode(DataType x) //新增节点开辟空间
{
     pLinkNode  newNode = (pLinkNode)malloc(sizeof(LinkNode));
     if (newNode == NULL)
     {
          printf("out of memory\n");
          exit(EXIT_FAILURE);
     }
     newNode->data = x;
     newNode->next = NULL;
     return newNode;
}
void Init(pLinkList pList)//初始化链表
{
     assert(pList);
     pList->phead = NULL;
}
void PrintList(pLinkList pList)//打印链表
{
     assert(pList);
     pLinkNode  cur = pList->phead;

     while (cur != NULL)
     {
          printf("%d->", cur->data);
          cur = cur->next;
     }
     printf("NULL\n");
}
void DestroyList(pLinkList pList)//销毁链表
{
     assert(pList);
     pLinkNode cur = pList->phead;
     pLinkNode del = NULL;
     while (cur != NULL)
     {
          del = cur;
          cur = cur->next;
          free(del);
     }
     pList->phead = NULL;
}
void PushFront(pLinkList pList, DataType x)//头插
{
     assert(pList);
     pLinkNode newNode = BuyNode(x);
    pLinkNode cur = pList->phead;
     newNode->next = cur;
     pList->phead = newNode;
}
void PushBack(pLinkList pList, DataType x) //尾插
{
     assert(pList);
     pLinkNode newNode = BuyNode(x);
     pLinkNode cur = pList->phead;
     if (cur == NULL)
     {
          pList->phead = newNode;
          return;
     }
     pLinkNode prev = NULL;
     while (cur!=NULL)
     {
          prev = cur;
          cur = cur->next;
     }

     prev->next= newNode;
}
void PopFront(pLinkList pList)    //头删
{
     pLinkNode cur = pList->phead;
     if (cur == NULL)
     {
          printf("该链表无元素可删\n");
     }
     else
     {
          pList->phead = cur->next;
          free(cur);
          cur = NULL;
     }

}
void PopBack(pLinkList pList)//尾删
{
     pLinkNode cur = pList->phead;
     pLinkNode prev = NULL;
     if (cur == NULL)
     {
          printf("该链表无元素可删\n");
     }
     else if (cur->next == NULL) //链表中只有一个元素
     {
          pList->phead = NULL;
          free(cur);
     }
     else

     {
          while (cur->next != NULL)
          {
              prev = cur;
              cur = cur->next;
          }
          free(cur);
          prev->next = NULL;
     }

}
void Insert(pLinkList pList, pLinkNode Pos, DataType x)//指定位置之前插入
{
     assert(pList);
     pLinkNode cur = pList->phead;
     pLinkNode newNode = BuyNode(x);
     if (Pos == cur)
     {
          PushFront(pList, x);
     }
     else if (Pos == NULL)
     {
          printf("输入位置错误\n");
          return;
     }
     else
     {
          while (cur)
          {
              if (cur->next == Pos)
              {
                   cur->next = newNode;
                   newNode->next = Pos;
              }
              cur = cur->next;
          }
     }
}
pLinkNode Find(pLinkList pList, DataType x) //公用的查找函数
{
     assert(pList);
     pLinkNode cur = pList->phead;
     while (cur!=NULL)
     {
          if (cur->data == x)
          {
              return cur;
          }
          cur = cur->next;
     }
     return NULL;
}
void Search(pLinkList pList, DataType x)//查找指定元素
{
     assert(pList);
     pLinkNode cur = NULL;
     cur = Find(pList, x);
     if (cur != NULL)
     {
          printf("该元素存在");
     }
     printf("该元素不存在\n");
}
void Remove(pLinkList pList, DataType x) //删除指定元素
{
     assert(pList);
     pLinkNode del = NULL;
     pLinkNode cur = NULL;
       DataType tmp;
     cur = Find(pList, x);
     if (cur == pList->phead)  //链表只有一个元素时
     {
          PopFront(pList);
     }
     else if (cur->next == NULL)  //cur现在指向最后一个元素
     {
          PopBack(pList);
     }
     else if (cur != NULL)
     {
          tmp = cur->data;
          cur->data = cur->next->data;
          cur->next->data = tmp;
          del = cur->next;
          cur->next = cur->next->next;
          free(del);
     }
     else
     {
          printf("该元素不存在\n");
     }

}
void RemoveALL(pLinkList pList, DataType x) //删除所有出现的元素
{
     assert(pList);
     pLinkNode del = NULL;
     pLinkNode cur = pList->phead;
     DataType tmp;
     while (cur != NULL)
     {
          cur = Find(pList, x);
          if (cur == NULL)
          {
              return;
          }
          if (cur == pList->phead)  //链表只有一个元素时
          {
              PopFront(pList);
          }
          else if (cur->next == NULL)  //cur现在指向最后一个元素
          {
              PopBack(pList);
          }
          else

          {
              tmp = cur->data;
              cur->data = cur->next->data;
              cur->next->data = tmp;
              del = cur->next;
              cur->next = cur->next->next;
              free(del);
          }

     }

}
void Erase(pLinkList pList, pLinkNode pos)//删除指定位置的元素
{
     assert(pList);
     pLinkNode prev = NULL;
     pLinkNode del = NULL;
     pLinkNode cur = pList->phead;
     if (pos == NULL)
     {
          printf("该位置不存在\n");
     }
     else if (cur == pos)
     {
          PopFront(pList);
     }
     else
     {
          while (cur !=pos)
          {
              prev = cur;
              cur = cur->next;
          }
          del = cur;
          prev->next = cur->next;
          free(del);
     }
}
void BubbleSort(pLinkList pList)//对链表进行冒泡排序
{
     assert(pList);
     pLinkNode cur = pList->phead;
     pLinkNode j = NULL;
     for (; cur != NULL; cur = cur->next)
     {
          for (j = cur->next; j != NULL; j = j->next)
          {
              if (cur->data>j->data)
              {
                   DataType tmp = cur->data;
                   cur->data = j->data;
                   j->data = tmp;
              }
          }
     }

}

 

test.c
 1 #include"LinkList.h"
 2 void menu()
 3 {
 4      printf("****************************************\n");
 5      printf("1.指定位置之前插入****2.打印链表********\n");
 6      printf("3.删除指定元素********4.删除所有指定的元素\n");
 7      printf("5.查找元素************6.链表排序*********\n");
 8      printf("7.头插****************8.尾插**************\n");
 9      printf("9.头删****************10.尾删**************\n");
10      printf("11.销毁链表*********** 0.退出**************\n");
11      printf("*******************************************\n");
12 
13 }
14 void Test()
15 {
16      int input;
17      DataType x;  //插入的元素
18      DataType pos ; //插入的位置
19      LinkList List;
20      Init(&List);  //一定要记得初始化
21      while (1)
22      {
23           menu();
24           printf("请选择一个操作:\n");
25           scanf("%d", &input);
26           switch (input)
27           {
28           case PRINT:
29               PrintList(&List);
30               break;
31           case PUSHF:
32               printf("请输入要插入的元素:\n");
33               scanf("%d", &x);
34              PushFront(&List,x);//头插
35              break;
36           case SEARCH:
37               printf("请输入要查找的元素:\n");
38               scanf("%d", &x);
39               Search(&List, x);
40               break;
41           case PUSHB:
42               printf("请输入要插入的元素:\n");
43               scanf("%d", &x);
44               PushBack(&List, x);//头插
45               break;
46           case POPB:
47               PopBack(&List);
48               break;
49           case SORT:
50               BubbleSort(&List);
51               break;
52           case POPF:
53               PopFront(&List);
54               break;
55           case INSERT:
56               printf("请输入要插入的位置,要插入的元素\n");
57               scanf("%d", &pos);
58               scanf("%d", &x);
59               Insert(&List, Find(&List, pos),x); //注意Find的参数
60               break;
61           case REMOVE:
62               printf("请输入删除的元素\n");
63               scanf("%d", &x);
64               Remove(&List, x);
65               break;
66           case REMOVEALL:
67               printf("请输入删除的元素\n");
68               scanf("%d", &x);
69               RemoveALL(&List, x);
70               break;
71           case DOSTROY:
72               DestroyList(&List);
73               break;
74           case EXIT:
75               DestroyList(&List);
76               exit(0);
77               break;
78           default:
79               printf("输入错误\n");
80               break;
81           }
82 
83      }
84 }
85 int main()
86 {
87      Test();
88      system("pause");
89      return 0;
90 }

 

posted @ 2017-01-19 10:36  xmc_2022  阅读(200)  评论(0编辑  收藏  举报