单向链表结构的实现以及基本功能

1、心里话与大家分享

在代码中所有的注释都是在我第一次自己做的时候,没做对产生了错误之后找到了错误的原因而注释,我相信大家并不是每一句代码都不明白,而是往往和我一样,在某一个地方很疑惑,或者不解,因此,我认为没有必要每一句都注释。我是用耿国华的C语言学习的,我相信我的一些问题也许是大家的一些问题,因此,我很高兴和大家一起分享我的学习心得,让我们一起进步,畅游在算法与数据结构之美中,冲冲冲。

2、单向链表结构的实现以及基本功能

/**
 *    在本节我们来学习线性单链表
 */

#include<stdio.h>
#include <mm_malloc.h>

#define MAXSIZE 15   // 常量的定义不需要分号也不需要等号  MAXSIZE = 5; 这样是错误的
#define OK  1
#define ERROR -1
#define NOTFOUND -2

typedef struct Node{

     char data;
     struct Node *next;

}Node,*LinkList;

int main(){
    LinkList creatLinkList();
    void createFromHead(LinkList L);
    void dispaly(LinkList L);
    void createFormTail(LinkList L);
    int getLinkListLength(LinkList L);
    int insert(LinkList L ,char elem,int index);
    int delete(LinkList L ,int index);
    int getElem(LinkList L,int index);
    int getIndex(LinkList L,char elem);

    LinkList *L =  creatLinkList();
   /* createFromHead(L);*/
    createFormTail(L);
    dispaly(L);
    printf("长度:%d\n",getLinkListLength(L));
    insert(L,'v',1);
    delete(L,4);
    getElem(L,1);
    getIndex(L,'a');
    dispaly(L);

}

//初始化单向链表
LinkList creatLinkList(){
    Node *p = (Node *)malloc(sizeof(Node));
    p->next = NULL;
    return p;
};

//头插法建立单向表
void createFromHead(LinkList L){

        Node *p;
         char c;
         int flag = 1;
         while(flag){
            c = getchar();
             if (c != '$'){
                 p = (Node *)malloc(sizeof(Node));
                 p->data = c ;
                 p->next = L->next;
                 L->next = p;
             }else{
                  flag = 0;

             }
         }

}

//尾插法建立单向表
void createFormTail(LinkList L){
    Node *p,*r;
    r = L;
    char c;
      int flag = 1;
      while(flag){
           c = getchar();
          if (c != '$'){
            p = (Node *)malloc(sizeof(Node));
            p->data = c;
            r->next = p;
            r = p;
          }else{
                r->next = NULL;
                flag = 0;
          }
      }
}

//遍历单向链表
void dispaly(LinkList L){
       Node *p = L;
    while (p->next != NULL){
         p = p->next;
          printf("%c\t",p->data);
    }
}

//得到单向链表的长度
int getLinkListLength(LinkList L) {
    Node *p = L;
    int length = 0;
    while (p->next != NULL) {
        p = p->next;
        length++;
    }
    return length;
}

//插入数据 返回1表示成功,-1表示失败
int insert(LinkList L ,char elem,int index){

    //插入为位置小于1肯定是不对的,毫无疑问的
    if (index < 1){
         printf("输入的位置不对!");
        return ERROR;
    }

        Node *pre,*r;
        pre = L;
         int j = 0;

        /* //一直遍历找到 插入位置的前一个节点
         while(pre->next != NULL){
             pre = pre->next;
              j++;
             if (j == index-1){
                 r = (Node *)malloc(sizeof(Node));
                 r->data = elem;
                 r->next = pre->next;
                 pre->next = r;
                 return OK;
             }
         }*/   //不要按照这样子写,这样子写的话,当你插入一个位置时,就会报错

        while(pre != NULL && j < index-1){//这是成立的条件,当遍历完还没找到插入的位置或者是找到插入的位置都跳出循环
              pre = pre ->next;
              j++;
        }

    if (pre == NULL){ //由于while循环结束肯能是因为pre ==NULL造成的所以要判断一下
           printf("插入的位置过大!");
        return ERROR;

    }

    //到达这一步肯定是意味着来到了
    r = (Node *)malloc(sizeof(Node));
    r->data = elem;
    r->next = pre->next;
    pre->next = r;
    return OK;

}
/**
 *    你应该会注意到插入是 pre != NULL && j < index-1
 *    然后删除是 pre->next != NULL && k <index-1
 *    那是因为插入数据的时候你可以插入到末尾,因此,这个时候即使是pre->next == NULL条件也是成立的
 *    所以以后如果pre-next == NULL对于末尾不成立那就用这个作为条件,如果成立那么就用pre == NULL作为条件
 */
//移除数据
int delete(LinkList L ,int index){
            Node *pre,*r;
            pre = L;
            int k = 0;

    if (index < 1){
        printf("要删除的位置不对!");
        return ERROR;
    }

    while(pre->next != NULL && k <index-1 ){
        pre =  pre->next;
        k++;
    }

    if (pre->next == NULL){
        printf("要删除的位置过大!");
        return ERROR;
    }
    r = pre->next;
    pre->next = r->next;
    free(r);//释放要删除的节点  刚开始没想到释放 我就直接写 pre->next = pre->next->next
    return OK;

}

//按序号查找
int getElem(LinkList L,int index){
    if (index < 1){
        printf("输入的位置不对!");
        return ERROR;
    }

    Node *p;
    p = L;
    int j = 0;
    while(p->next != NULL){

        p = p->next;
        j++;
        if (j == index){
            printf("位置%d 对应的数据为:%c\n",index,p->data);
            return p->data;
        }

    }
    return ERROR;

}

//按值查找
int getIndex(LinkList L,char elem){

    Node *p;
    p = L;
    int index = 0;
    while(p->next != NULL){

        p = p->next;
        index++;
        if (p->data == elem ){
            printf("数据 %c 在表中的位置为:%d\n",p->data,index);
            return index;
        }

    }
    return ERROR;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值