zoukankan      html  css  js  c++  java
  • 串的链块表示,操作复杂,不实用

    串的链块表示

    #include <stdio.h>
    #include <stdlib.h>
    
    #define OK 1
    #define ERROR 0
    #define SRUE 1
    #define FALSE 0
    
    typedef int Status;
    
    #define CHUNKSIZE 5
    
    typedef struct Chunk
    {
        char ch[CHUNKSIZE];
        struct Chunk *next;
    }Chunk;
    
    typedef struct 
    {
        Chunk * head, *tail;    /* 串的头和尾指针*/
        int curlen;             /* 串的当前长度 */ 
    }LString;
    
    /* 生成一个其值等于chars的串S */
    Status StrAssign(LString *S, char * chars)
    {
        if(!S->head) {  /* 头结点不存在 */ 
            S->head = (Chunk *)malloc(sizeof(Chunk));   /* 创建头结点 */
            S->tail = S->head;
            S->head->next = NULL;
        }
        if(!S->head->next) {
            S->head->next = (Chunk *)malloc(sizeof(Chunk)); /* 创建第一个结点 */
            S->tail = S->head->next;           /* 尾指针指向第一个结点 */
            S->head->next->next = NULL;
            S->curlen = 0;                    /* 字符元素清零 */
        }
    
        Chunk * p = S->head->next;        /* 指向第一个结点 */ 
        int chunklen = 0;
        for(int i=0; chars[i] != ''; i++,S->curlen++) {
            p->ch[chunklen++] = chars[i];   
            if(chunklen % CHUNKSIZE == 0) { /* 数组到达末尾,则新开结点 */
                Chunk * q = (Chunk *)malloc(sizeof(Chunk));
                q->next = p->next;
                p->next = q;    /* 插入到末尾 */
                S->tail = q;    /* 尾指针指向末尾结点 */
                p = q;          /* 指向新插入点 */
                chunklen = 0;
            } 
        }
        while(chunklen < CHUNKSIZE)
            p->ch[chunklen++] = '#'; /* 最后剩余空间填满 # */
        return OK;
    }
    
    
    /* 返回串S的元素个数 */
    int StrLength(LString S)
    {
        return S.curlen;
    }
    
    
    /* 清空字符串,并释放S所占的空间 */
    Status ClearString(LString *S)
    {
        int index = 0;
        while(S->head) {
            S->tail = S->head->next;
            free(S->head);
            index++;
            S->head = S->tail;
        }
        printf("free %d
    ",index);
        S->curlen = 0;
        return OK;
    }
    
    
    /* 比较S,T,若S>T返回值>0 ,若S=T,返回0,若S<T,返回值<0 */
    int StrCompare(LString S, LString T)
    {
        if(!S.head->next || !T.head->next)
            return 0;
        int chunklen = 0;
        Chunk * pS = S.head->next;  /* 指向第一个结点 */
        Chunk * pT = T.head->next;
        for(int i=0; i<S.curlen && i<S.curlen; i++) {
            if(pS->ch[chunklen] != pT->ch[chunklen]) 
                return pS->ch[chunklen] - pT->ch[chunklen];
            chunklen++;
            if(chunklen % CHUNKSIZE == 0) {
                pS = pS->next;
                pT = pT->next;
                chunklen = 0;
            }
        }
        return S.curlen - T.curlen;
    }
    
    /* 用T返回由S1,S2拼接成的串 */
    Status Concat(LString *T, LString S1, LString S2)
    {
        // ... 未完成,这链块拼接真的不是那么简单,纠结在于最后的结点并不匹配,
        // 直接链表指指针的方式根本无法完成嘛
        if(!T->head) {  /* 头结点不存在 */ 
            T->head = (Chunk *)malloc(sizeof(Chunk));   /* 创建头结点 */
            T->tail = T->head;
            T->head->next = NULL;
        }
        T->head->next = S1.head->next;
        S1.tail->next = S2.head->next;
        T->curlen = S1.curlen + S2.curlen;
        return OK;
    }
    
    void PrintStr(LString S)
    {
        if(!S.head) return;
        Chunk * p = S.head->next;   /* 指向第一个结点 */
        
        for(int chunklen=0,i=0; p && i<S.curlen; i++) {
            printf("%c",p->ch[chunklen++]);
            if(chunklen % CHUNKSIZE == 0)  { /* 当前结点已经遍历,指向下一个结点 */
                p = p->next;
                chunklen = 0;
            }
        }
        printf("
    ");
    }
    
    int main()
    {
        LString S1,S2,T;
        S1.head = NULL;
        S2.head = NULL;
        T.head = NULL;
    
        StrAssign(&S1,"Hello World");
        StrAssign(&S2,"This is a hello world");
        PrintStr(S1);
        PrintStr(S2);
        printf("compare %d
    ",StrCompare(S1,S2));
        Concat(&T,S1,S2);
        PrintStr(T);
        ClearString(&T);
        ClearString(&S1);
        ClearString(&S2);
        printf("OK");
    }
    

    可以看输出结果

    最后一个结点填充#号,而拼接的时候如果只是把链表指向重新定向一下是不行的,没法去掉最后一个结点问题。而如果用一个一个复制的方法,那还不如用数组。强行改造也不行,一样效率低。

  • 相关阅读:
    Git常用命令整理
    JavaScript常用代码书写规范
    程序猿常用英语单词汇总
    15个常用的javaScript正则表达式
    [Java复习] 服务注册中心 (Eureka, Zookeeper)
    [Java复习] 面试突击
    [Java复习] 面试突击
    [Java复习] 面试突击
    [Java复习] Spring Cloud
    [Java复习] 微服务
  • 原文地址:https://www.cnblogs.com/wjundong/p/11628937.html
Copyright © 2011-2022 走看看