数据结构---链表

链表: 是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer).

优点: 使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理.

缺点: 链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大.


 

链表类型

单向链表

它包含两个域,一个信息域和一个指针域.

struct Node
{
    EleType element;
    struct Node *next;
};

 

含头指针的示意图:

双向链表

每个节点有两个连接:一个指向前一个节点,(当此“连接”为第一个“连接”时,指向空值或者空列表);而另一个指向下一个节点,(当此“连接”为最后一个“连接”时,指向空值或者空列表)

struct Node
{
    EleType element;
    struct Node *next;
    struct Node *prev;
};

 

示意图:

循环链表

作为单向链表或者双向链表的一种变形----首节点和末节点连接在一起

具体实现(C语言)

图形描述实现函数:

1. 删除某个节点

 

2. 增加某个节点

 

3. 其余类似

单向链表---此处将结构放在实现函数中而非头文件中

头文件 list.h罗列除具体实现的函数原型

#ifndef _List_H_
#define _List_H_

#define EleType int

struct Node;
typedef struct Node *PtrToNode;
typedef PtrToNode List;
typedef PtrToNode Position;

List Init();
List CreatList();
void PrintList(List list);
List MakeEmpty(List list);
int IsEmpty(List list);
int IsLast(Position pos,List list);
Position Find(EleType x,List list);
void Delete(EleType x,List list);
Position FindPrevious(EleType x,List list);
void Insert(EleType x,List list,Position pos);
void DeleteList(List list);
Position Header(List list);  //not implement
Position First(List list);   //not implement
Position Advance(Position pos);  //not implement
EleType Retrieve(Position pos);  //not implement

#endif

 各函数的具体实现

#include<stdio.h>
#include<stdlib.h>
#include "list.h"
typedef struct Node
{
    EleType element;
    struct Node *next;
}Node;

List Init()
{
    List list;
    list=(Node *)malloc(sizeof(Node));
    list->next=NULL;
    return list;
}

List CreatList()
{
    int num,i;
    int element;
    List list;
    Position pos;
    list=Init();
    pos=list;
    printf("How long the list would you want to creat!\n");
    scanf("%d",&num);
    for(i=0;i<num;i++)
    {
        scanf("%d",&element);  //if the element is not int,change
        Insert(element,list,pos);
        pos=pos->next;
    }
    return list;
}

int IsEmpty(List list)
{
    return list->next==NULL;
}

int IsLast(Position pos,List list)
{
    return pos->next==NULL;
}

Position Find(EleType x,List list)
{
    Position p;

    p=list->next;
    while(p!=NULL&&p->element!=x)
        p=p->next;

    return p;
}

//It means the position before position(element of x)
Position FindPrevious(EleType x,List list)
{
    Position p;
    p=list;
    while(p->next!=NULL&&p->next->element!=x)
        p=p->next;
    return p;
}

void Delete(EleType x,List list)
{
    Position p,temp;
    p=FindPrevious(x,list);

    if(!IsLast(p,list))
    {
        temp=p->next;
        p->next=temp->next;
        free(temp);   //free the space
    }
}

void Insert(EleType x,List list,Position pos)
{
    Position temp;
    temp=(Node*)malloc(sizeof(Node));
    if(temp==NULL)
    {
        printf("Out of space\n");
        return;
    }
    temp->element=x;
    temp->next=pos->next;
    pos->next=temp;
}

void DeleteList(List list)
{
    Position p,temp;
    p=list->next;
    list->next=NULL;
    while(p!=NULL)
    {
        temp=p->next;
        free(p);
        p=temp;
    }
}

void PrintList(List list)
{
    Position temp;
    temp=list->next;
    printf("Header-->");
    while(temp!=NULL)
    {
        printf("%d-->",temp->element);
        temp=temp->next;
    }
    printf("NULL\n");
}
View Code

 (相对比较简陋,如有错误,望指出~thank you!)

测试代码

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

int main()
{
    List list;
    list=CreatList();
    PrintList(list);
}
View Code

 注:只给了非常简单的测试代码

 

双向链表---此处将结构放入头文件

----ps: 个人认为双向链表写的比单向好些(上面的写的那么糟糕, 不妨看看此处)

关于结构放入头文件和放入.c文件的区别见另一篇文章:

头文件  link.h

#ifndef _Linked_H
#define _Linked_H
#define EleType int

struct Node
{
    EleType element;
    struct Node *prev;
    struct Node *next;
};

struct List
{
    struct Node *header;
    int size;
};

typedef struct Node Node;
typedef struct List List;
typedef Node *PtrToNode;
typedef PtrToNode PNode;

void PrintList(List list);  
List CreatList(int len);
PNode CreatNode(EleType k);
PNode Search(List l,EleType k);    
void Insert(List *l,PNode node);
void Delete(List *l,PNode node);
void DeleteList(List *l);
int IsEmpty(List l);
PNode GetKnode(List l,int k);
int ChangeKthNode(List *l,int k,EleType newele);
void InsertEnd(List *l,PNode pnode);
void InsertKth(List *l,int k,PNode pnode);
void ChangeTwoNodes(List *l,PNode pn1,PNode pn2);
void QuickSort(List *l,int left,int right);

#endif 

 

 具体函数实现: linkmethod.c 

(PS: 看到一篇博客上说实现链表的10来种功能, 就尽可能多地写了以下方法---如有重要需补充,望指出!)

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

/*creat node pointer for list*/
PNode CreatNode(EleType k)
{
    PNode node;
    node=malloc(sizeof(Node));
    if(node==NULL)
    {
        printf("Out of space!\n");
        return NULL;
    }
    node->element=k;
    return node;
}

/*creat a list,it's a little bad*/
List CreatList(int len)
{
    List list;
    int i;
    EleType k;
    if(len==0)
    {
        list.header=NULL;
        list.size=0;
        return list;
    }
    scanf("%d",&k);
    list.header=CreatNode(k);
    list.size=1;
    for(i=1;i<len;i++)
    {
        scanf("%d",&k);
        Insert(&list,CreatNode(k));
    }
    return list;
}

/*print(show) the list*/
void PrintList(List list)
{
    PNode temp;
    temp=list.header;
    while(temp!=NULL)
    {
        printf("%d-->",temp->element);
        temp=temp->next;
    }
    printf("null\n");
}

/*get the node(pointer) with the element is k */
PNode Search(List l,EleType k)
{
    PNode pos;
    pos=l.header;
    while(pos!=NULL&&pos->element!=k)
        pos=pos->next;
    return pos;
}

/*insert the node to list*/
void Insert(List *l,PNode node)
{
    node->next=l->header;
    if(l->header!=NULL)
        l->header->prev=node;
    l->header=node;
    node->prev=NULL;
    l->size+=1;
}

/*delete the node in the list*/
void Delete(List *l,PNode node)
{
    if(node->prev!=NULL)
        node->prev->next=node->next;
    else
        l->header=node->next;
    if(node->next!=NULL)
        node->next->prev=node->prev;
    l->size-=1;
    free(node);
}

/*delete the all nodes in list,header->null*/
void DeleteList(List *l)
{
    PNode temp,p;
    p=l->header;
    l->header=NULL;
    while(p!=NULL)
    {
        temp=p->next;
        free(p);
        p=temp;
    }
    l->size=0;
}

/*exam whether the list is null? 1---null  0---not null*/
int IsEmpty(List l)
{
    return l.header==NULL;
}

/*Get the Kth node in the list*/
PNode GetKnode(List l,int k)
{
    if(k>l.size||k<1)
    {
        printf("The k is exceed the list!!\n");
        return NULL;
    }
    int i;
    PNode pnode;
    pnode=l.header;
    for(i=1;i<k;i++)
    {
        pnode=pnode->next;
    }
    return pnode;
}

/*Change the Kth node's element*/
int ChangeKthNode(List *l,int k,EleType newele)
{
    if(k>l->size||k<1)
        return 0;
    PNode temp;
    int i;
    temp=l->header;
    for(i=1;i<k;i++)
        temp=temp->next;
    temp->element=newele;
    return 1;
}

/*Add a node in the end of list*/
void InsertEnd(List *l,PNode pnode)
{
    PNode pend;
    pend=GetKnode(*l,l->size);
    if(pend==NULL)
        l->header=pnode;
    else
    {
        pend->next=pnode;
        pnode->prev=pend;
        pnode->next=NULL;
        l->size+=1;
    }    
}

/*Add a node in the Kth position of list*/
void InsertKth(List *l,int k,PNode pnode)
{
    PNode pkth;
    pkth=GetKnode(*l,k);
    if(pkth==NULL)
    {
        printf("failed! k exceed the list length!\n");
        return;
    }
    if(k==1)
    {
        Insert(l,pnode);
    }
    else
    {
        pnode->prev=pkth->prev;
        pnode->next=pkth;
        pkth->prev->next=pnode;
        pkth->prev=pnode;
        l->size+=1;
    }
}

int IsInList(List l,PNode pnode)
{
    PNode temp;
    temp=Search(l,pnode->element);
    return pnode==temp;
}

/*change the two nodes'element*/
void ChangeTwoNodes(List *l,PNode pn1,PNode pn2)
{
    if(IsInList(*l,pn1)!=1||IsInList(*l,pn2)!=1)
    {
        printf("error: There exist node not in List!\n");
        return;
    }
    EleType temp;
    temp=pn1->element;
    pn1->element=pn2->element;
    pn2->element=temp;
}

/*Do quick sort to list*/
void QuickSort(List *l,int left,int right)
{
    if(left>=right)
    {
        return;
    }
    int q;
    int i=left-1,j;
    EleType x=GetKnode(*l,right)->element;
    for(j=left;j<right;j++)
    {
        if(GetKnode(*l,j)->element<=x)
        {
            i++;
            ChangeTwoNodes(l,GetKnode(*l,i),GetKnode(*l,j));
        }
    }
    ChangeTwoNodes(l,GetKnode(*l,i+1),GetKnode(*l,right));
    q=i+1;
    QuickSort(l,left,q-1);
    QuickSort(l,q+1,right);
}
View Code

 

 测试代码   linktest.c

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

int main()
{
    int i;
    List list;
    PNode pnode;
    list.header=CreatNode(4);
    list.size=1;
    Insert(&list,CreatNode(6));
    Insert(&list,CreatNode(5));
    PrintList(list);
    printf("list's len='%d\n",list.size);
    pnode=Search(list,4);
    Delete(&list,pnode);
    PrintList(list);
    pnode=GetKnode(list,3);
    if(pnode!=NULL)
        printf("the 3th node is=%d\n",pnode->element);
    printf("the change is success?: %d\n",ChangeKthNode(&list,2,20));
    pnode=CreatNode(30);
    InsertKth(&list,2,pnode);
    PrintList(list);
    ChangeTwoNodes(&list,Search(list,5),Search(list,20));
    PrintList(list);
    QuickSort(&list,1,list.size);
    PrintList(list);
    printf("%d\n",list.size);
}
View Code

 

具体应用实例

近期内补上~

 

posted @ 2015-04-15 01:23  Nooooooo  阅读(297)  评论(0编辑  收藏  举报