第四周 項目二 【建立單鏈表算法庫】

問題:
/* 
*Copyright (c)2016,煙臺大學計算機與控制工程學院 
*All rights reserved. 
*文件名稱:項目2.cbp 
*作    者:樑凱
*完成日期:2016年9月22日 
*版 本 號:v1.0 
* 
*問題描述:按照“0207將算法變程序”部分建議的方法,建設自己的專業基礎設施算法庫。這一週,建的是單鏈表的算法庫。  
           算法庫包括兩個文件:  
            
           頭文件:linklist.h,包含定義順序表數據結構的代碼、宏定義、要實現算法的函數的聲明;  
           源文件:linklist.cpp,包含實現各種算法的函數的定義 
            
           請採用程序的多文件組織形式,建立如上的兩個文件,另外再建立一個源文件(如main.cpp),編制main函數,完成相關的測試工作。 
*輸入描述:無 
*程序輸出:按教材實驗題2.2要求的輸出 
*/ 
 


 

頭文件 list.h 代碼:
#ifndef LIST_H_INCLUDED
#define LIST_H_INCLUDED

#include<stdio.h>
#include<malloc.h>
typedef int ElemType;//int類型 運用typedef方便快捷
typedef struct LNode
{
    ElemType data;
    struct LNode *next;//定義單鏈表節點類型
}LinkList;
void CreateListF(LinkList *&L,ElemType a[],int n);//頭插法建立單鏈表
void CreateListR(LinkList *&L,ElemType a[],int n);//尾插法建立單鏈表
void InitList(LinkList *&L);//初始化線性表
void DestroyList(LinkList *&L);//銷燬線性表
bool ListEmpty(LinkList *L);//判斷線性表是否爲空
int ListLength(LinkList *L);//求線性表的長度
void DispList(LinkList *L);//輸出線性表
bool GetElem(LinkList *L,int i,ElemType &e);//求線性表中某個元素值
int LocateElem(LinkList *L,ElemType e);//按元素值查找
bool ListInsert(LinkList *&L,int i,ElemType e);//插入數據元素
bool ListDelete(LinkList *&L,int i,ElemType &e);//刪除數據元

#endif // LIST_H_INCLUDE


 

函數實現 list.cpp 代碼
#include "list.h"
void CreateListF(LinkList *&L,ElemType a[],int n)//頭插法建立單鏈表
{
    LinkList *s;
    int i;
    L=(LinkList *)malloc(sizeof(LinkList));     //創建頭結點 其next域置爲NULL
    L->next=NULL;
    for (i=0; i<n; i++)//循環建立數據節點
    {
        s=(LinkList *)malloc(sizeof(LinkList));
        s->data=a[i];                //創建數據結點*s
        s->next=L->next;            //將*s插在原開始結點之前,頭結點之後
        L->next=s;
    }
}
void CreateListR(LinkList *&L,ElemType a[],int n)//尾插法建立單鏈表
{
   LinkList *s,*r;
    int i;
    L=(LinkList *)malloc(sizeof(LinkList));     //創建頭結點
    L->next=NULL;
    r=L;                    //r始終指向終端結點,開始時指向頭結點
    for (i=0; i<n; i++)//循環建立數據節點
    {
        s=(LinkList *)malloc(sizeof(LinkList));
        s->data=a[i];            //創建數據結點*s
        r->next=s;          //將*s插入*r之後
        r=s;
    }
    r->next=NULL;           //終端結點next域置爲NULL
}
void InitList(LinkList *&L)//初始化線性表
{
    L=(LinkList *)malloc(sizeof(LinkList));     //創建頭結點,其next域置爲NULL
    L->next=NULL;
}
void DestroyList(LinkList *&L) //銷燬線性表
{
   LinkList *pre=L,*p=L->next;//pre指向*p的前驅節點
    while (p!=NULL)//掃描單鏈表L
    {
        free(pre);//釋放*pre節點
        pre=p;    //pre 、p同步後移一個單位
        p=pre->next;
    }
    free(pre);//循環結束後,p爲NULL,pre指向尾節點,釋放它
}
bool ListEmpty(LinkList *L)//判斷線性表是否爲空
{
   return(L->next==NULL);
}
int ListLength(LinkList *L)//求線性表的長度
{
    LinkList *p=L;//p指向頭節點,i置爲0,(即 頭節點的序號爲0)
    int i=0;
    while (p->next!=NULL)
    {
        i++;
        p=p->next;
    }
    return(i);//循環結束,p指向尾節點,其序號n爲節點個數
}
void DispList(LinkList *L)//輸出線性表
{
     LinkList *p=L->next;//p指向開始節點
    while (p!=NULL)//p不爲NULL,輸出*p節點的data域
    {
        printf("%d ",p->data);
        p=p->next;//p移向下一個節點
    }
    printf("\n");
}
bool GetElem(LinkList *L,int i,ElemType &e)//求線性表中某個元素值
{
    int j=0;
    LinkList *p=L;//p指向頭節點,j置爲0,(即頭節點的序號爲0)
    while (j<i && p!=NULL)
    {
        j++;
        p=p->next;
    }
    if (p==NULL)            //不存在第i個數據結點, 返回false
        return false;
    else                    //存在第i個數據結點 返回true
    {
        e=p->data;
        return true;
    }
}
int LocateElem(LinkList *L,ElemType e)//按元素值查找
{
    LinkList *p=L->next;//p指向開始節點,n置爲1(即開始節點的序號爲1)
    int n=1;
    while (p!=NULL && p->data!=e)//查找data值爲e的節點,其序號爲n
    {
        p=p->next;
        n++;
    }
    if (p==NULL)
        return(0);//不存在元素值爲e的節點,返回0
    else
        return(n);//存在元素值爲e的節點,返回其邏輯序號n
}
bool ListInsert(LinkList *&L,int i,ElemType e)//插入數據元素
{
    int j=0;
    LinkList *p=L,*s;//p指向頭節點,j置爲0(即頭節點的序號爲0)
    while (j<i-1 && p!=NULL) //查找第i-1個結點
    {
        j++;
        p=p->next;
    }
    if (p==NULL)    //未找到位序爲i-1的結點
        return false;
    else            //找到位序爲i-1的結點*p
    {
        s=(LinkList *)malloc(sizeof(LinkList));//創建新結點*s 其data域爲e
        s->data=e;
        s->next=p->next;                        //將*s插入到*p之後
        p->next=s;
        return true;
    }

}
bool ListDelete(LinkList *&L,int i,ElemType &e)//刪除數據元素
{
    int j=0;
    LinkList *p=L,*q;//p指向頭節點,j置爲0(即頭節點的序號爲0)
    while (j<i-1 && p!=NULL)    //查找第i-1個結點
    {
        j++;
        p=p->next;
    }
    if (p==NULL)                //未找到位序爲i-1的結點
        return false;
    else                        //找到位序爲i-1的結點*p
    {
        q=p->next;              //q指向要刪除的結點
        if (q==NULL)
            return false;           //若不存在第i個結點,返回false
        e=q->data;
        p->next=q->next;        //從單鏈表中刪除*q結點
        free(q);                //釋放*q結點
        return true;
    }
}


 

主函數代碼:
#include <iostream>
using namespace std;
#include "list.h"

int main()
{
    LinkList *h;
    ElemType E;
    int k;
    //初始化單鏈表h
    InitList(h);
    //聲明
    ElemType a[5]={1,5,6,8,3};
    //頭插法插入字符
    CreateListF(h, a, 5);
    //輸出單鏈表h
    DispList(h);
    //輸出單鏈表長度
    printf("鏈表長度:%d\n",ListLength(h));
    //判斷空表
    if((ListEmpty(h))>0)
        printf("是空表\n");
    else
        printf("不是空表\n");
     //輸出指定元素
    if(GetElem(h, 3, E))
        printf("找到了第3個元素值爲:%d\n", E);
    else
        printf("第3個元素超出範圍!\n");
    //查找元素地址
    if((k=LocateElem(h, 3))>0)
        printf("找到了,值爲3的元素是第 %d 個\n", k);
    else
        printf("值爲1的元素沒有找到 \n");
    //插入元素
    printf("在第2個位置插入元素10\n");
    ListInsert(h, 2, 10);
    //輸出單鏈表h
    DispList(h);
    //刪除元素
    printf("刪除第3個位置的元素\n");
    ListDelete(h,3,E);
    //輸出單鏈表h
    DispList(h);
    //銷燬單鏈表
    printf("銷燬單鏈表\n");
    DestroyList(h);
    return 0;
}
運行結果:
<img src="https://img-blog.csdn.net/20160923103646916" alt="" />
心得體會:
鏈表這一塊不簡單,需要不斷琢磨
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章