【數據結構】—— 單向鏈表ADT

抽象數據類型(Abstract Data Type,ADT)是計算機科學中具有類似行爲的特定類別的數據結構的數學模型;或者具有類似語義的一種或多種程序設計語言的數據類型。抽象數據類型是間接定義的,通過其上的可執行的操作以及這些操作的效果的數學約束(與可能的代價)。——維基百科


接口頭文件LinkedList.h

 /**************************************************************
*	Multi-Include-Prevent Section
**************************************************************/
#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        : void *InitList(LinkList L);
 *	@description : initialize an empty linked list with only the head node without value
 *	@param		 : L(the head pointer)
 *	@return		 : LNode(the new head node) or Status
 *  @notice      : None
 */
void *InitList(LinkedList L);

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

/**
 *  @name        : void *InsertList(LinkedList L, int i, ElemType x)
 *	@description : insert node q after node p
 *	@param		 : LinkedList L, int i, ElemType x
 *	@return		 : L(the head pointer) or Status
 *  @notice      : None
 */
void *InsertList(LinkedList L, int i, ElemType x);

/**
 *  @name        : void *DeleteList(LinkedList L, ElemType x)
 *	@description : delete the first node after the node p and assign its value to e
 *	@param		 : LinkedList L, ElemType x
 *	@return		 : L(the head pointer)
 *  @notice      : None
 */
void *DeleteList(LinkedList L, ElemType x);

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

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

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

/**
 *  @name        : void IsLoopList(LinkedList L)
 *	@description : judge whether the linked list is looped
 *	@param		 : L(the head pointer)
 *	@return		 : L(the head pointer)
 *  @notice      : None
 */
void 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 pointer)
 *	@return		 : L(the head pointer)
 *  @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 pointer)
 *	@return		 : LNode*
 *  @notice      : choose to finish
 */
LNode* FindMidNode(LinkedList L);

/**
 *  @name        : void *Create()
 *	@description : Create a linked list
 *	@param		 : None
 *	@return		 : L(the head pointer)
 *  @notice      : None
 */
void *Create();

/**
 *  @name        : int LinkedList_length(LinkedList L)
 *	@description : Measure the length of linked list
 *	@param		 : L(the head pointer)
 *	@return		 : Length of linked list
 *  @notice      : None
 */
int LinkedList_length(LinkedList L);

/**
 *  @name        : void *Create_loopLinkedList()
 *	@description : Create a loop LinkedList
 *	@param		 : None
 *	@return		 : L(the head pointer)
 *  @notice      : None
 */
void *Create_loopLinkedList();

/**
 *  @name        : int InputNumber()
 *	@description : Input number
 *	@param		 : None
 *	@return		 : int
 *  @notice      : None
 */
int InputNumber();

 /**************************************************************
*	End-Multi-Include-Prevent Section
**************************************************************/
#endif

使用接口main.c

#include <stdio.h>
#include <stdlib.h>
#include "linkedList.h"

int main()
{
    LinkedList head; // Head of LinkedList.
    int flag = 0; // Whether exist LinkedList.
    while(SUCCESS)
    {
        system("cls");
        printf("\n\n\n---------------------------\n");
        printf(">>> 1.Creat.               \n");
        printf(">>> 2.Print.               \n");
        printf(">>> 3.Initialize.          \n");
        printf(">>> 4.Destroy.             \n");
        printf(">>> 5.Insert.              \n");
        printf(">>> 6.Delete.              \n");
        printf(">>> 7.Search.              \n");
        printf(">>> 8.Reverse.             \n");
        printf(">>> 9.Reverse odd&even.    \n");
        printf(">>> 10.Find MidNode.       \n");
        printf(">>> 11.Judge loop.         \n");
        printf(">>> 12.Create a loop one.  \n");
        printf(">>> 13.Exit.               \n");
        printf("---------------------------\n");
        if(flag)
        {
            TraverseList(head, visit); // Print LinkedList.
        }
        else
        {
            printf("No LinkedList.\n");
        }
        printf("---------------------------\n");
        printf("----->>> Please input your choice:");
        switch(InputNumber())
        {
        case 1:
            head = Create();
            flag = 1;
            break;
        case 2:
            if(flag)
            {
                TraverseList(head, visit);
            }
            else
            {
                printf("No LinkedList.\n");
            }
            break;
        case 3:
            head = InitList(head);
            flag = 1;
            break;
        case 4:
            if(flag)
            {
                DestroyList(head);
                flag = 0;
            }
            else
            {
                printf("No LinkedList.\n");
            }
            break;
        case 5:
            if(flag)
            {
                int i;
                ElemType x;
                printf("Where to insert? ");
                scanf("%d", &i);
                printf("Input data:");
                scanf("%d", &x);
                head = InsertList(head, i, x);
            }
            else
            {
                printf("No LinkedList.\n");
            }
            break;
        case 6:
            if(flag)
            {
                ElemType x;
                printf("What to delete? ");
                scanf("%d", &x);
                DeleteList(head, x);
            }
            else
            {
                printf("No LinkedList.\n");
            }
            break;
        case 7:
            if(flag)
            {
                int i;
                LinkedList temp;
                printf("Where it is? ");
                scanf("%d", &i);
                temp = SearchList(head, i);
                printf("What you find is %d.\n", temp->data);
            }
            else
            {
                printf("No LinkedList.\n");
            }
            break;
        case 8:
            if(flag)
            {
                head = ReverseList(head);
            }
            else
            {
                printf("No LinkedList.\n");
            }
            break;
        case 9:
            if(flag)
            {
                head = ReverseEvenList(head);
            }
            else
            {
                printf("No LinkedList.\n");
            }
            break;
        case 10:
            if(flag)
            {
                LinkedList mid, temp = head;
                mid = FindMidNode(head);
                if(LinkedList_length(head)%2 == 0)
                {
                    printf("The data of middle Node is %d\n", mid->data);
                }
                else // The length of LinkList is even.Print the middle two values of the LinkedList.
                {
                    while(temp->next != mid) // Find the middle node which is near the head node.
                    {
                        temp = temp->next;
                    }
                    printf("The data of middle Node is %d and %d\n", temp->data, temp->next->data);
                }
            }
            else
            {
                printf("No LinkedList.\n");
            }
            break;
        case 11:
            if(flag)
            {
                IsLoopList(head);
            }
            else
            {
                printf("No LinkedList.\n");
            }
            break;
        case 12:
            head = Create_loopLinkedList();
            break;
        case 13:
            exit(0);
        default:
            break;
        }
        system("pause");
    }
    return 0;
}

實現接口LinkedList.c

#include "linkedList.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/**
 *  @name        : void *InitList(LinkList L);
 *	@description : initialize an empty linked list with only the head node without value
 *	@param		 : L(the head pointer)
 *	@return		 : LNode(the new head node) or Status
 *  @notice      : None
 */
void *InitList(LinkedList L)
{
    if(!L) // Judge if the head node exists
    {
        return ERROR;
    }
    L = (LinkedList)malloc(sizeof(LNode)); // Allocate memory for the head node
    if(L == NULL) // Judge if memory is sufficient
    {
        return OVERFLOW;
    }
    printf("Successfully initialize the LinkedList.\n");
    L->next = NULL;
    return L;
}

/**
 *  @name        : Status DestroyList(LinkedList L)
 *	@description : destroy a linked list, free all the nodes
 *	@param		 : L(the head pointer)
 *	@return		 : Status
 *  @notice      : None
 */
Status DestroyList(LinkedList L)
{
    LinkedList p;
    p = L;
    while(p)
    {
        p = p->next;
        free(L); // Free up memory space.
        L = p;
    }
    printf("Successfully destroy the LinkedList!\n");
    return SUCCESS;
}

/**
 *  @name        : void *InsertList(LinkedList L, int i, ElemType x)
 *	@description : insert node q after node p
 *	@param		 : LinkedList L, int i, ElemType x
 *	@return		 : L(the head pointer) or Status
 *  @notice      : None
 */
void *InsertList(LinkedList L, int i, ElemType x)
{
    if(L == NULL)
    {
        printf("Something wrong.\nThe LinkedList may not exist or there is only one node.");
        return ERROR;
    }
    LinkedList pre;
    pre = L;
    for(int temp=1; temp < i; temp++)
    {
        pre = pre->next;
    }
    LinkedList q;
    q = (LinkedList)malloc(sizeof(LNode));
    q->data = x;
    q->next = pre->next;
    pre->next = q;

    printf("Successfully insert node!\n");
    return L;
}

/**
 *  @name        : void *DeleteList(LinkedList L, ElemType x)
 *	@description : delete the first node after the node p and assign its value to e
 *	@param		 : LinkedList L, ElemType x
 *	@return		 : L(the head pointer)
 *  @notice      : None
 */
void *DeleteList(LinkedList L, ElemType x)
{
    if(L == NULL || L->next == NULL)
    {
        printf("Something wrong.\nThe LinkedList may not exist or there is only one node.");
        return ERROR;
    }
    LinkedList q, pre;
    q = L->next;
    while(q->data != x)
    {
        pre = q;
        q = q->next;
    }
    pre->next = q->next;
    free(q);
    printf("Successfully delete node!");
    return L;
}

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

/**
 *  @name        : void *SearchList(LinkedList L, int i)
 *	@description : find the first node in the linked list according to e
 *	@param		 : L(the head pointer), e
 *	@return		 : L(the head pointer)
 *  @notice      : None
 */
void *SearchList(LinkedList L, int i) // Maybe can create a function to realize find by value.
{
    if(L == NULL || L->next == NULL)
    {
        printf("Something wrong.\nThe LinkedList may not exist or there is only one node.");
        return NULL;
    }
    int j = 1;
    LinkedList p = L->next;
    if(i == 1)
    {
        return L;
    }
    if(i < 1)
    {
        return NULL;
    }
    while(p && i>j)
    {
        p = p->next;
        j++;
    }
    return p;
}

/**
 *  @name        : void *ReverseList(LinkedList L)
 *	@description : reverse the linked list
 *	@param		 : L(the head pointer)
 *	@return		 : L(the head pointer)
 *  @notice      : None
 */
void *ReverseList(LinkedList L)
{
	if(L == NULL)
    {
        printf("Something wrong.\nThe LinkedList may not exist.");
        return ERROR;
    }
	LNode*p,*q,*r;
	p = L->next; L->next = NULL;
	q = r = NULL;
	while(p){
		q = p->next;
		p->next = r;
		r = p;
		p = q;
	}
	L->next = r;
	return L;
}

/**
 *  @name        : void IsLoopList(LinkedList L)
 *	@description : judge whether the linked list is looped
 *	@param		 : L(the head pointer)
 *	@return		 : L(the head pointer)
 *  @notice      : None
 */
void IsLoopList(LinkedList L)
{
    if(L == NULL || L->next == NULL)
    {
        printf("Something wrong.\nThe LinkedList may not exist or there is only one node.");
        return ERROR;
    }
    LinkedList fast, slow;
    slow = L;
    fast = L->next;
    while(1)
    {
        if(!fast || !fast->next)
        {
            printf("It is not a loop LinkedList.\n");
            return SUCCESS;
        }
        else if(fast == slow || fast->next == slow) // Fast pointer catches up or exceeds slow pointer.
        {
            printf("It is a loop LinkedList.\n");
            return SUCCESS;
        }
        else
        {
            slow = slow->next;
            fast = fast->next->next;
        }
    }
}

/**
 *  @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 pointer)
 *	@return		 : L(the head pointer)
 *  @notice      : choose to finish
 */
LNode* ReverseEvenList(LinkedList L)
{
    LinkedList cur = L->next;
    LinkedList pre;
    LinkedList phead = (LinkedList)malloc(sizeof(LNode));
    phead->next = NULL;
    LinkedList ph = phead;

    while( cur && cur->next )
    {
        pre = cur;
        ph->next = pre->next; // First point to the second node in two groups.
        ph = ph->next; // Move ph pointer.
        cur = cur->next->next; // Move the cur pointer for the next round of swaps.
        ph->next = pre; // Point to the first node in two sets.
        ph = ph->next; // Move ph pointer.
    }
    ph->next = cur; // Finally point to the remaining element if cur is NULL or odd.
    return phead;
}

/**
 *  @name        : LNode* FindMidNode(LinkedList L)
 *	@description : find the middle node in the linked list
 *	@param		 : L(the head pointer)
 *	@return		 : LNode*
 *  @notice      : choose to finish
 */
LNode* FindMidNode(LinkedList L)
{
    if(L == NULL || L->next == NULL)
    {
        return L;
    }
    LinkedList fast, slow;
    fast = slow = L;
    while(fast!=NULL)
    {
        if(fast->next == NULL)
        {
            fast = fast->next;
        }
        else
        {
            fast = fast->next->next;
        }
        slow = slow->next;
    }
    return slow;
}

/**
 *  @name        : void *Create()
 *	@description : Create a linked list
 *	@param		 : None
 *	@return		 : L(the head pointer)
 *  @notice      : None
 */
void *Create()
{
    LinkedList head;
    LinkedList p, s;
    ElemType x, cycle = 1;
    head = (LinkedList)malloc(sizeof(LNode));
    p = head;
    while(cycle)
    {
        printf("Please input the data(input non-integer to exit):");
        if(scanf("%d", &x) == 1)
        {
            s = (LinkedList)malloc(sizeof(LNode));
            s->data = x;
            p->next = s;
            p = s;
        }
        else
        {
            cycle = 0;
        }
    }
    printf("Successfully create a LinkedList!\n");
    p->next = NULL;
    return head;
}

/**
 *  @name        : int LinkedList_length(LinkedList L)
 *	@description : Measure the length of linked list
 *	@param		 : L(the head pointer)
 *	@return		 : Length of linked list
 *  @notice      : None
 */
int LinkedList_length(LinkedList L)
{
    int k = 0;
    while(L != NULL)
    {
        k++;
        L = L->next;
    }
    return k;
}

/**
 *  @name        : void *Create_loopLinkedList()
 *	@description : Create a loop LinkedList
 *	@param		 : None
 *	@return		 : L(the head pointer)
 *  @notice      : None
 */
void *Create_loopLinkedList()
{
    int i, length = 0, data = 0;
	LinkedList pTail = NULL, p_new = NULL;
	LinkedList pHead = (LinkedList)malloc(sizeof(LNode));

	if (NULL == pHead)
	{
		printf("Memory allocation failed!\n");
		return OVERFLOW;
	}

	pHead->data = 0;
	pHead->next = pHead;
	pTail = pHead;

	printf("Please enter the length of the LinkedList:");
	scanf("%d", &length);

	for (i=1; i<length+1; i++)
	{
		p_new = (LinkedList)malloc(sizeof(LNode));

		if (NULL == p_new)
		{
			printf("Memory allocation failed!\n");
			return OVERFLOW;
		}

		printf("Please enter the data for No.%d node:", i);
		scanf("%d", &data);

		p_new->data = data;
		p_new->next = pHead; // The last node always points to the head node.
		pTail->next = p_new;
		pTail = p_new;
	}

	return pHead;
}

/**
 *  @name        : int InputNumber()
 *	@description : Input number
 *	@param		 : None
 *	@return		 : int
 *  @notice      : None
 */
int InputNumber()
{
	int num = 0; // Store converted numbers.
	int status = 0; // Flag status.
	char str[100]; // Receive string.
	do
	{
		scanf("%s", str);
		status = SUCCESS;
		for (int i = 0; str[i] != '\0'; i++)
		{
			// Check for illegal characters.
			if (i == 0)
            {
				if (str[i] == '-' || str[i] == '+')
					continue;
			}
			else
			{
				if (str[i] < '0' || str[i] > '9')
				{
					status = ERROR;
				}
			}
		}
		if (status == ERROR)
        {
			printf("No such choice, input it again:");
		}
		else
		{
			int i = 0;
			// Convert string to number.
			for (i = 0, num = 0; str[i] != '\0'; i++)
			{
				if (i == 0)
                {
					if (str[i] == '-' || str[i] == '+')
					{
						continue;
					}
					else
					{
						num *= 10;
						num += (str[i] - 48);
					}
				}
				else
				{
					num *= 10;
					num += (str[i] - 48);
				}
			}
			if (str[0] == '-')
            {
				num = -num;
			}
			// Check if the number entered is out of bounds.
			if (i >= 10)
			{
				printf("Overflow, please input again:");
				status = ERROR;
			}
		}
	} while (status == ERROR);
	return num;
}

LinkedList.exe

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章