关于c语言实现单向链表以及双向链表的基本操作

关于c语言实现单向链表以及双向链表的基本操作

单向链表代码以及一些测试用的函数
#include "linkedList.h"
#include 
#include 
#include 

//工具函数
void select(LinkedList h);
LinkedList getNode(LinkedList h,int n);
LinkedList creatNode();
void pri(ElemType e);
int sgets();

int main(void)
{
    int n = 0;
    LinkedList p1,h;

    while(n <= 0 || n > 1000){
        puts("请输入要创建的链表节点数(1~1000):");
        n = sgets();
    }
    for(int i=1;i<=n;i++)
        if(i == 1) {
            InitList(&h);
            h->data = i;
        }
        else{
            p1 = (LinkedList)malloc(sizeof(LNode));
            p1->data = i;
            p1->next = h;
            h = p1;
        }
        puts("\t\t\t\t****请选择链表操作****");
        puts("\t\t\t\t1.销毁链表并退出程序");
        puts("\t\t\t\t2.插入一个节点到链表");
        puts("\t\t\t\t3.删除一个节点并输出节点数据");
        puts("\t\t\t\t4.遍历链表并输出链表数据");
        puts("\t\t\t\t5.查询链表是否包含某数");
        puts("\t\t\t\t6.反转链表");
        puts("\t\t\t\t7.判断链表是否出现循环");
        puts("\t\t\t\t8.将链表中偶数节点和前节点交换");
        puts("\t\t\t\t9.查找中间节点");
    
        select(h);
    
        return 0;

}
//选项调用
void select(LinkedList h)
{
    char ch;
    ElemType a,*e;
    fflush(stdin);
    e = &a;
    puts("请选择你要进行的操作(取第一个输入):");
    switch(ch = getchar()){
            case '1':
                DestroyList(&h);
                exit(0);
            case '2':
                puts("请输入你要在第几个节点后插入:");
                a = sgets();
                if(InsertList(getNode(h,a), creatNode()))puts("操作成功");
                else puts("操作失败");
                break;
            case '3':
                puts("请输入你要删除第几个节点之后的节点:");
                a = sgets();
                if(DeleteList(getNode(h,a),e))printf("操作成功,删除节点数据为%d\n",*e);
                else puts("操作失败");
                break;
            case '4':
                TraverseList(h,pri);break;
            case '5':
                puts("请输入要查询的数:");
                a = sgets();
                if(SearchList(h, a))puts("链表中有该数据");
                else puts("链表中不存在该数据");
                break;
            case '6':
                if(ReverseList(&h))puts("操作成功");
                else puts("未知错误");
                break;
            case '7':
                if(IsLoopList(h))puts("链表存在循环");
                else puts("链表不存在循环");
                break;
            case '8':
                h = ReverseEvenList(&h);
                puts("操作成功");
                break;
            case '9':
                FindMidNode(&h);
                break;
            default :puts("请在正确的范围输入!");
        }
        select(h);
}
//找到需要用到的节点
LinkedList getNode(LinkedList h,int n)
{
    if(n<1) return NULL;
    LinkedList p = h;

    for(int i = 1;i < n;i++)
    {
        p = p->next;
        if(i < n-1 && p->next == NULL)
            return NULL;
    }
    return p;

}
//创建一个节点
LinkedList creatNode()
{
    LinkedList q;
    q = (LinkedList)malloc(sizeof(LNode));
    puts("请输入您要插入的数据:");
    q->data = sgets();
    return q;
}
void pri(ElemType e)
{
    printf("%d->",e);
}
//自定义输入函数
int sgets()
{
    char * ret_val;
    char * find;
    char  st[100];

    fflush(stdin);
    ret_val = fgets(st,100,stdin);
    if(ret_val){
        find = strchr(st,'\n');
        if(find)*find = '\0';
        else while(getchar() != '\n')
                continue;
    }

   return atoi(ret_val);
}

头文件以及链表接口

#ifndef LINKEDLIST_H_INCLUDED
#define LINKEDLIST_H_INCLUDED

/**************************************************************

*	Macro Define Section
  **************************************************************/

#define OVERFLOW -1

/**************************************************************

*	Struct Define Section
  **************************************************************/

// define element type
typedef int ElemType;

// define struct of linked list
typedef struct LNode {
	ElemType data;
  	struct LNode *next;
} LNode, *LinkedList;

// define Status
typedef enum Status {
	ERROR,
	SUCCESS
} Status;


/**************************************************************

*	Prototype Declare Section
  **************************************************************/

/**

 *  @name        : Status InitList(LinkList *L);
 *  @description : initialize an empty linked list with only the head node without value
 *  @param		 : L(the head node)
 *  @return		 : Status
 *  @notice      : None
    */
    Status InitList(LinkedList *L);

/**

 *  @name        : void DestroyList(LinkedList *L)
 *  @description : destroy a linked list, free all the nodes
 *  @param		 : L(the head node)
 *  @return		 : None
 *  @notice      : None
    */
    void DestroyList(LinkedList *L);

/**

 *  @name        : Status InsertList(LNode *p, LNode *q)
 *  @description : insert node q after node p
 *  @param		 : p, q
 *  @return		 : Status
 *  @notice      : None
    */
    Status InsertList(LNode *p, LNode *q);

/**

 *  @name        : Status DeleteList(LNode *p, ElemType *e)
 *  @description : delete the first node after the node p and assign its value to e
 *  @param		 : p, e
 *  @return		 : Status
 *  @notice      : None
    */
    Status DeleteList(LNode *p, ElemType *e);

/**

 *  @name        : void TraverseList(LinkedList L, void (*visit)(ElemType e))
 *  @description : traverse the linked list and call the funtion visit
 *  @param		 : L(the head node), visit
 *  @return		 : None
 *  @notice      : None
    */
    void TraverseList(LinkedList L, void (*visit)(ElemType e));

/**

 *  @name        : Status SearchList(LinkedList L, ElemType e)
 *  @description : find the first node in the linked list according to e
 *  @param		 : L(the head node), e
 *  @return		 : Status
 *  @notice      : None
    */
    Status SearchList(LinkedList L, ElemType e);

/**

 *  @name        : Status ReverseList(LinkedList *L)
 *  @description : reverse the linked list
 *  @param		 : L(the head node)
 *  @return		 : Status
 *  @notice      : None
    */
    Status ReverseList(LinkedList *L);

/**

 *  @name        : Status IsLoopList(LinkedList L)
 *  @description : judge whether the linked list is looped
 *  @param		 : L(the head node)
 *  @return		 : Status
 *  @notice      : None
    */
    Status IsLoopList(LinkedList L);

/**

 *  @name        : LNode* ReverseEvenList(LinkedList *L)
 *  @description : reverse the nodes which value is an even number in the linked list, input: 1 -> 2 -> 3 -> 4  output: 2 -> 1 -> 4 -> 3
 *  @param		 : L(the head node)
 *  @return		 : LNode(the new head node)
 *  @notice      : choose to finish
    */
    LNode* ReverseEvenList(LinkedList *L);

/**

 *  @name        : LNode* FindMidNode(LinkedList *L)
 *  @description : find the middle node in the linked list
 *  @param		 : L(the head node)
 *  @return		 : LNode
 *  @notice      : choose to finish
    */
    LNode* FindMidNode(LinkedList *L);
  #endif

#include “linkedList.h”
#include
#include
/**

  *  @name        : Status InitList(LinkList *L);
  *  @description : initialize an empty linked list with only the head node without value
  *  @param		 : L(the head node)
  *  @return		 : Status
  *  @notice      : None
     */
     Status InitList(LinkedList *L) {
        *L = (LinkedList)malloc(sizeof(LNode));
        if(!(*L)) return ERROR;
        (*L)->next = NULL;
        return SUCCESS;
     }
 
 /**
  • @name : void DestroyList(LinkedList *L)
  • @description : destroy a linked list, free all the nodes
  • @param : L(the head node)
  • @return : None
  • @notice : None
    */
    void DestroyList(LinkedList *L) {
    LinkedList p;
    while(*L){
    p = (*L)->next;
    free(*L);
    *L = p;
    }
    }

/**

  • @name : Status InsertList(LNode *p, LNode *q)
  • @description : insert node q after node p
  • @param : p, q
  • @return : Status
  • @notice : None
    */
    Status InsertList(LNode *p, LNode *q) {
    if(!p) { puts(“指定节点不存在!”); return ERROR; }
    q->next = p->next;
    p->next = q;
    return SUCCESS;

}
/**

  • @name : Status DeleteList(LNode *p, ElemType *e)
  • @description : delete the first node after the node p and assign its value to e
  • @param : p, e
  • @return : Status
  • @notice : None
    */
    Status DeleteList(LNode *p, ElemType *e) {
    if (!p) {puts(“指定节点不存在”); return ERROR; }
    if (!(p->next)) { puts(“该节点已是最后一个节点!”); return ERROR; }
    LNode *t = p->next;
    *e = t->data;
    p->next = t->next;
    free(t);
    return SUCCESS;
    }

/**

  • @name : void TraverseList(LinkedList L, void (*visit)(ElemType e))
  • @description : traverse the linked list and call the funtion visit
  • @param : L(the head node), visit
  • @return : None
  • @notice : None
    */
    void TraverseList(LinkedList L, void (*visit)(ElemType e)) {
    while(L){
    visit(L->data);
    L = L->next;
    }
    printf("\n");
    }

/**

  • @name : Status SearchList(LinkedList L, ElemType e)
  • @description : find the first node in the linked list according to e
  • @param : L(the head node), e
  • @return : Status
  • @notice : None
    */
    Status SearchList(LinkedList L, ElemType e) {
    while(L){
    if(L->data == e)return SUCCESS;
    L = L->next;
    }
    return ERROR;
    }

/**

  • @name : Status ReverseList(LinkedList *L)

  • @description : reverse the linked list

  • @param : L(the head node)

  • @return : Status

  • @notice : None
    */
    Status ReverseList(LinkedList *L) {
    if(!(*L)) return ERROR;
    LinkedList p1,p2,p3;
    p1 = *L;
    p2 = p3 = p1->next;
    p1->next = NULL;

    while(p3){
       p3 = p3->next;
       p2->next = p1;
       p1 = p2;
       p2 = p3;
    }
    *L = p1;
    return SUCCESS;
    

    }

/**

  • @name : Status IsLoopList(LinkedList L)
  • @description : judge whether the linked list is looped
  • @param : L(the head node)
  • @return : Status
  • @notice : None
    */
    Status IsLoopList(LinkedList L) {
    if(!L)return ERROR;
    LinkedList p1,p2;
    while( (!p1)&&(!p2) )
    {
    p2 = p2->next->next;
    p1 = p1->next;
    if(p1 == p2)return SUCCESS;
    }
    return ERROR;
    }

/**

  • @name : LNode* ReverseEvenList(LinkedList *L)
  • @description : reverse the nodes which value is an even number in the linked list, input: 1 -> 2 -> 3 -> 4 output: 2 -> 1 -> 4 -> 3
  • @param : L(the head node)
  • @return : LNode(the new head node)
  • @notice : choose to finish
    /
    LNode
    ReverseEvenList(LinkedList *L) {
    LinkedList p1,p2,h,t;
    int n = 0;
    h=p1 = *L;
    while(p1->next)
    {
    p2 = p1->next;
    p1->next = p2->next;
    p2->next = p1;
    if(++n == 1)h = p2;
    else t->next = p2;
    t = p1;
    p1 = p1->next;
    if(!p1)break;
    }
    return h;
    }

/**

  • @name : LNode* FindMidNode(LinkedList *L)

  • @description : find the middle node in the linked list

  • @param : L(the head node)

  • @return : LNode

  • @notice : choose to finish
    /
    LNode
    FindMidNode(LinkedList *L) {
    LinkedList p1,p2;
    p1 = p2 = *L;

    while (p2)
    {
    p2 = p2->next->next;
    p1 = p1->next;
    if (p2->next == NULL) {
    printf(“中间节点的数据为%d\n”,p1->data);
    break;
    }
    if (p2->next->next == NULL) {
    printf(“中间节点数据为%d-%d\n”,p1->data,p1->next->data);
    break;
    }
    }
    return p1;
    }




##### 双向链表的代码

```c
#include "duLinkedList.h"
#include 
#include 
#include 

void select(DuLinkedList h);
void pri(ElemType e);
DuLinkedList refresh(DuLinkedList h);
DuLinkedList getNode(DuLinkedList h,int n);
DuLinkedList creatNode();
int sgets();

int main(void)
{
   int n = 0;
   DuLinkedList p1,p2,h;

   while(n <= 0 || n > 1000){
       puts("请输入要创建的链表节点数(1~1000):");
       n = sgets();
   }
   for(int i = 1;i <= n;i++)
       if(i == 1) {
           InitList_DuL(&h);
           h->data = i;
           p1 = h;
       }
       else{
           p2 = (DuLinkedList)malloc(sizeof(DuLNode));
           p2->data = i;
           p2->next = NULL;
           p2->prior = p1;
           p1->next = p2;
           p1 = p2;
       }
       puts("\t\t\t\t****请选择链表操作****");
       puts("\t\t\t\t1.销毁链表并退出程序");
       puts("\t\t\t\t2.插入一个节点到链表指定节点前");
       puts("\t\t\t\t3.插入一个节点到链表指定节点后");
       puts("\t\t\t\t4.删除一个节点并输出节点数据");
       puts("\t\t\t\t5.遍历链表并输出链表数据");
       select(h);
   return 0;

}
void select(DuLinkedList h)
{
   char ch;
   ElemType a,*e;
   fflush(stdin);
   e = &a;
   puts("请选择你要进行的操作(取第一个输入):");
   switch(ch = getchar()) {
       case '1':
           DestroyList_DuL(&h);
           exit(0);
       case '2':
           puts("请输入你要在第几个节点前插入:");
           a = sgets();
           if(InsertBeforeList_DuL(getNode(h,a), creatNode())) puts("操作成功");
           else puts("操作失败:指定节点不存在");
           h = refresh(h);
           break;
       case '3':
           puts("请输入你要在第几个节点后后插入:");
           a = sgets();
           if(InsertAfterList_DuL(getNode(h,a), creatNode())) puts("操作成功");
           else puts("操作失败:指定节点不存在");
           break;
       case '4':
           puts("请输入你要删除第几个节点之后的节点:");
           a = sgets();
           if(DeleteList_DuL(getNode(h,a),e)) printf("操作成功,删除节点数据为%d\n",*e);
           else puts("操作失败");
           break;
       case '5':
           TraverseList_DuL(h,pri);break;
       default :puts("请在正确的范围输入!");
   }
    select(h);

}
//自定义输入函数
int sgets()
{
   char * ret_val;
   char * find;
   char  st[100];

   fflush(stdin);
   ret_val = fgets(st,100,stdin);
   if(ret_val){
       find = strchr(st,'\n');
       if(find)*find = '\0';
       else while(getchar() != '\n')
               continue;
   }
   return atoi(ret_val);

}
//找到需要用到的节点
DuLinkedList getNode(DuLinkedList h,int n)
{
   if(n<1) return NULL;
   DuLinkedList p = h;

   for(int i = 1;i < n;i++)
   {
       p = p->next;
       if(i < n-1 && p->next == NULL)
           return NULL;
   }
   return p;

}
//创建一个节点
DuLinkedList creatNode()
{
   DuLinkedList q;
   q = (DuLinkedList)malloc(sizeof(DuLNode));
   puts("请输入您要插入的数据:");
   q->data = sgets();
   q->next = q->prior = NULL;
   return q;
}
void pri(ElemType e)
{
   printf("%d->",e);
}
DuLinkedList refresh(DuLinkedList h)
{
   while(h->prior) h = h->prior;
   return h;

}

头文件以及接口实现

  • /**************************************************************
    
    *	Multi-Include-Prevent Section
      **************************************************************/
    
    #ifndef DULINKEDLIST_H_INCLUDED
    #define DULINKEDLIST_H_INCLUDED
    
    /**************************************************************
    
    *	Macro Define Section
      **************************************************************/
    
    #define OVERFLOW -1
    
    /**************************************************************
    
    *	Struct Define Section
      **************************************************************/
    
    // define element type
    typedef int ElemType;
    
    // define struct of linked list
    typedef struct DuLNode {
    	ElemType data;
      	struct DuLNode *prior,  *next;
    } DuLNode, *DuLinkedList;
    
    // define status
    typedef enum Status {
    	ERROR,
    	SUCCESS,
    } Status;
    
    
    /**************************************************************
    
    *	Prototype Declare Section
      **************************************************************/
    
    /**
    
     *  @name        : Status InitList_DuL(DuLinkedList *L)
     *  @description : initialize an empty linked list with only the head node
     *  @param		 : L(the head node)
     *  @return		 : Status
     *  @notice      : None
        */
        Status InitList_DuL(DuLinkedList *L);
    
    /**
    
     *  @name        : void DestroyList_DuL(DuLinkedList *L)
     *  @description : destroy a linked list
     *  @param		 : L(the head node)
     *  @return		 : status
     *  @notice      : None
        */
        void DestroyList_DuL(DuLinkedList *L);
    
    /**
    
     *  @name        : Status InsertBeforeList_DuL(DuLNode *p, LNode *q)
     *  @description : insert node q before node p
     *  @param		 : p, q
     *  @return		 : status
     *  @notice      : None
        */
        Status InsertBeforeList_DuL(DuLNode *p, DuLNode *q);
    
    /**
    
     *  @name        : Status InsertAfterList_DuL(DuLNode *p, DuLNode *q)
     *  @description : insert node q after node p
     *  @param		 : p, q
     *  @return		 : status
     *  @notice      : None
        */
        Status InsertAfterList_DuL(DuLNode *p, DuLNode *q);
    
    /**
    
     *  @name        : Status DeleteList_DuL(DuLNode *p, ElemType *e)
     *  @description : delete the first node after the node p and assign its value to e
     *  @param		 : p, e
     *  @return		 : status
     *  @notice      : None
        */
        Status DeleteList_DuL(DuLNode *p, ElemType *e);
    
    /**
    
     *  @name        : void TraverseList_DuL(DuLinkedList L, void (*visit)(ElemType e))
     *  @description : traverse the linked list and call the funtion visit
     *  @param		 : L(the head node), visit
     *  @return		 : Status
     *  @notice      : None
        */
        void TraverseList_DuL(DuLinkedList L, void (*visit)(ElemType e));
    
    
     /**************************************************************
    
    *	End-Multi-Include-Prevent Section
      **************************************************************/
      #endif
    * #include "duLinkedList.h"
      #include 
      #include 
      /**
    
       *  @name        : Status InitList_DuL(DuLinkedList *L)
       *  @description : initialize an empty linked list with only the head node
       *  @param		 : L(the head node)
       *  @return		 : Status
       *  @notice      : None
          */
          Status InitList_DuL(DuLinkedList *L) {
             (*L) = (DuLinkedList)malloc(sizeof(DuLNode));
             if(!(*L))return ERROR;
             (*L)->next = NULL;
             (*L)->prior = NULL;
             return SUCCESS;
          }
    
      /**
    
       *  @name        : void DestroyList_DuL(DuLinkedList *L)
       *  @description : destroy a linked list
       *  @param		 : L(the head node)
       *  @return		 : status
       *  @notice      : None
          */
          void DestroyList_DuL(DuLinkedList *L) {
             DuLinkedList p;
             while(*L){
                 p = (*L)->next;
                 free(*L);
                 *L = p;
             }
          }
    
      /**
    
       *  @name        : Status InsertBeforeList_DuL(DuLNode *p, LNode *q)
       *  @description : insert node q before node p
       *  @param		 : p, q
       *  @return		 : status
       *  @notice      : None
          */
          Status InsertBeforeList_DuL(DuLNode *p, DuLNode *q) {
             if(!p)return ERROR;
             if(p->prior){
                 q->prior = p->prior;
                 p->prior->next = q;
             }
             q->next = p;
             p->prior = q;
             return SUCCESS;
          }
    
      /**
    
       *  @name        : Status InsertAfterList_DuL(DuLNode *p, DuLNode *q)
       *  @description : insert node q after node p
       *  @param		 : p, q
       *  @return		 : status
       *  @notice      : None
          */
          Status InsertAfterList_DuL(DuLNode *p, DuLNode *q) {
             if(!p)return ERROR;
             if(p->next){
                 q->next = p->next;
                 p->next->prior = q;
             }
             q->prior = p;
             p->next = q;
             return SUCCESS;
          }
    
      /**
    
       *  @name        : Status DeleteList_DuL(DuLNode *p, ElemType *e)
       *  @description : delete the first node after the node p and assign its value to e
       *  @param		 : p, e
       *  @return		 : status
       *  @notice      : None
          */
          Status DeleteList_DuL(DuLNode *p, ElemType *e) {
             if (!p) {
                 puts("指定节点不存在!");
                 return ERROR;
             }
             else if (!(p->next)) {
                 puts("该节点后面没有节点!");
                 return ERROR;
             }
             DuLNode *t = p->next;
             *e = p->next->data;
             p->next = p->next->next;
             if (p->next) p->next->prior = p;
             free(t);
             return SUCCESS;
          }
    
      /**
    
       *  @name        : void TraverseList_DuL(DuLinkedList L, void (*visit)(ElemType e))
       *  @description : traverse the linked list and call the funtion visit
       *  @param		 : L(the head node), visit
       *  @return		 : Status
       *  @notice      : None
          */
          void TraverseList_DuL(DuLinkedList L, void (*visit)(ElemType e)) {
             if(L->prior) L = L->prior;
             while(L){
                 visit(L->data);
                 L = L->next;
             }
             printf("\n");
          }
    
    

你可能感兴趣的:(关于c语言实现单向链表以及双向链表的基本操作)