吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1033|回复: 1
收起左侧

[C&C++ 转载] 【笔记】带头节点的单链表的C语言实现

[复制链接]
天地玄黄 发表于 2020-11-29 11:25
什么是线性表
线性表就是一组数据的集合以某种特定方式排列。该排列方式中除第一个元素和最后一个元素外,每一个元素的前面和后面都有其他元素。第一个元素前面没有其他元素,最后一个元素后面没有其他元素。

线性表在计算机中有不同的存储方式,昨天我写的实现方式是顺序存储也就是说数据前后的数据在计算机的存储器中是一个一个挨着存的。今天的实现是单链表形式,数据在计算机中的存放位置仅仅是在逻辑上前后挨着,在计算机的存储器里并没有放在一起,数据之间通过指针实现逻辑上的互联。

一个线性表的单链表存储形式的存储形式如图:

单链表

单链表

该图中,head指向的为单链表的头结点,该单链表中有两个数据(数据没有在图上写出来,鼠标写字太难了{:301_971:} )。
从图中可以看出:
  • 链表中的每个节点包含一个数据和一个指针(指向下一个节点)。
  • 链表有一个头节点,不存储元素内容,头节点的指向存储第一个元素的结点。
  • 线性表为空时,头节点指针项为空(用0表示)。
  • 线性表不为空时,链表中存储最后一个元素的指针项为空,表示后面没有元素了。
  • 线性表元素从1开始标号。存储结构中,可以将头结点的编号视为0,实现逻辑编号与物理编号的统一。
  • head指针指向头结点。

单链表实现:list.h
typedef char EleType;
typedef struct node{
    EleType data;
    struct node * next;
} ChainNode;
typedef struct{
    ChainNode * head;
} List;
List * CreateList(void);
void DestroyList(List *);
void ClearList(List *);
int ListInsert(List *,int,EleType);
int ListDelete(List *,int);
int ListAppend(List *,EleType);
int TraverseList(List *,int (*)(EleType *));
int GetElement(List * l,int n,EleType * data);
ChainNode* NewChainNode(EleType);
ChainNode* GetAddr(List *,int );

List* CreateList(void){
    List * l = 0;
    ChainNode * p = 0;
    EleType * data = 0;
    l = (List *)malloc(sizeof(List));
    if(l == 0) return 0;
    p = NewChainNode(*data);
    if(p==0) return 0;
    l->head = p;
    return l;
}

void DestroyList(List * l){
    ClearList(l);
    free(l->head);
}

void ClearList(List * l){
    while(l->head->next){
        ListDelete(l,1);
    }
}

int ListInsert(List * l,int n,EleType data){
    ChainNode * p = 0;
    ChainNode * newp = 0;
    p = GetAddr(l,n-1);
    if( p == 0 ) return 0;
    newp = NewChainNode(data);
    if(newp == 0 ) return 0;
    newp->next = p->next;
    p->next = newp;
    return 1;
}

int ListDelete(List * l,int n){
    ChainNode * p = 0;
    ChainNode * temp = 0;
    p = GetAddr(l,n-1);
    if(p==0) return 0;
    temp = p->next;
    if(temp==0) return 0;
    p->next = temp->next;
    return 1;
}

int ListAppend(List * l,EleType data){
    ChainNode * p = 0;
    ChainNode * newp = 0;
    p = l->head;
    while(p->next)
        p = p->next;
    newp = NewChainNode(data);
    if(newp == 0 ) return 0;
    p->next = newp;
    return 1;
}

int TraverseList(List * l, int (*f)(EleType  *data)){
    ChainNode * p = 0;
    int cnt = 0;
    EleType * temp =0;
    p = l->head->next;
    while(p){
        cnt++;
        temp = &(p->data);
        if(f(temp) == 0) return cnt;
        p = p->next;
    }
    return -1;
}

int GetElement(List * l,int n,EleType * data){
    ChainNode * p = 0;
    if(n < 1) return 0;
    p = GetAddr(l,n);
    if(p == 0) return 0;
    (*data)=p->data;
    return 1;
}

ChainNode * NewChainNode(EleType data){
    ChainNode * p = 0;
    p = (ChainNode *)malloc(sizeof(ChainNode));
    if(p == 0) return 0;
    p->data = data;
    p->next = 0;
    return p;
}

ChainNode * GetAddr(List * l,int pos){
    ChainNode * p = 0;
    int cnt = 0;
    p = l->head;
    if(pos < 0) return 0;
    while(p && cnt++ < pos){
        p = p->next;
    }
    if(cnt < pos) return 0;
    return p;
}


对list.h进行测试(检验程序的鲁棒性):m.c
#include"list.h"

#define RIGHT 0
#define WRONG 1
#define CREATELIST 0
#define LISTAPPEND 1
#define LISTINSERT 2
#define LISTDELETE 3
#define GETELEMENT 4
#define CLEARLIST  5
#define titleTest printf("your:");
#define titleSystem printf("\nsyst:");

int putE(EleType*);

void showResult(List*, int no, char *answer);

char* strArr[] =
{

   "---------CreateList Test---------",
   "---------ListAppend Test---------",
   "---------ListInsert Test---------",
   "---------ListDelete Test---------",
   "---------GetElement Test---------",
   "---------ClearList Test---------",   
};

main()
{

     char* arr = "assembly";

     int n = 0;
     List* list;
     char chArr[10] = {0,0,0,0,0,0,0,0,0,0};
     char ch;

     list = CreateList();
     puts(strArr[CREATELIST]);
     if(!list) { puts("createList wrong!"); return; }
     else      { puts("createList no nullpointer!");}
     puts(""); getch();

     for(n=0; arr[n]; n++) ListAppend(list, arr[n]);
     showResult(list, LISTAPPEND, "assembly");

     ListInsert(list,1,'<');
     ListInsert(list,10,'>');
     ListInsert(list,7,'-');
     n = ListInsert(list,0,'0');
     n = n + ListInsert(list,13,'0');
     n = n + ListInsert(list,-1,'0');

     showResult(list, LISTINSERT, "<assem-bly>");
     if(n) puts("insert error!");

     n = 0;     
     ListDelete(list,1);
     ListDelete(list,10);
     ListDelete(list,6);
     ListDelete(list,8);
     ListDelete(list,1);
     ListDelete(list,5);

     n = ListDelete(list,0);
     n = n + ListDelete(list, 6);
     n = n + ListDelete(list, -1);
     showResult(list, LISTDELETE, "sseml");
     if(n) puts("list delete error!");

     n = 0;

     GetElement(list, 5, &ch); chArr[0] = ch;
     GetElement(list, 1, &ch); chArr[1] = ch;
     GetElement(list, 3, &ch); chArr[2] = ch;
     n = GetElement(list, 6, &ch);

     puts(strArr[GETELEMENT]);
     titleTest printf("%s",chArr);
     titleSystem puts("lse");
     if(n) puts("getelement error!");
     puts(""); getch();

     ClearList(list);
     showResult(list, CLEARLIST, "");

}

void showResult(List* list, int no, char *answer)
{
     puts(strArr[no]);
     titleTest TraverseList(list,putE);  
     titleSystem puts(answer);
     puts(""); getch();

}

int putE(EleType* e)
{
    printf("%c", *e);

    return 1;
}

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

ciker_li 发表于 2020-11-29 15:47
感谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 21:46

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表