• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

尼古拉斯豆

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

数据结构--线性表--链式存储

跟线性存储一样,我添加了17,18两个函数.不过感觉17不够好,用到了goto.

编译器:gcc

#include <stdio.h>

typedef int elemType;

struct sNode{
       elemType data;
       struct sNode *next; 
};

/* 1.初始化线性表,即置线性表的头指针为空 */
void initList(struct sNode **hp) 
{
    *hp = NULL;
    return;         
} 

/* 2.清楚线性表L中所有元素,即释放单链表L中所有节点,使之成为一个空表 */ 
void clearList(struct sNode **hp)
{
    if(*hp == NULL) return;

    struct sNode *temp,*next;
    temp=*hp;

    while(temp != NULL)
    {
        next = temp->next;
        free(temp);
        temp = next; 
    }
    *hp = NULL; 
    
    return; 
}
 
/* 3.返回单链表的长度*/
int sizeList(struct sNode *hp)
{
    int size=0;

    while(hp!=NULL)
    {
        size+=1;
        hp=hp->next;                    
    } 
    return size; 
} 
/* 4.检查单链表是否为空,空返回1,否则返回0*/ 
int emptyList(struct sNode *hp) 
{
    if(hp == NULL) return 1; 
    else return 0; 
} 
/* 5.返回单链表中第pos个节点的元素值,若pos超出范围,则停止程序运行*/
elemType getElem(struct sNode *hp, int pos) 
{
    int size = sizeList(hp);

    if(pos<1 && pos>size)
    {
        printf("pos位置越界.\n");
        exit(1); 
    }

    int i = 1;
    while(i!=pos)
    {
        i+=1;
        hp=hp->next; 
    } 
    
    return hp->data; 
} 
/* 6.遍历一个单链表*/ 
void travelList(struct sNode *hp) 
{
    while(hp != NULL)
    {
        printf("%d ",hp->data);
        hp = hp->next; 
    } 
} 
/* 7.从单链表中查找值为x的第一个元素,若查找成功返回该节点data域的存储地址,否则返回NULL*/
elemType *findList(struct sNode *hp, elemType x)
{
    if(hp == NULL)
    { 
        printf("链表为空,无法查找%d\n",x);
        return NULL; 
    } 
    while(hp != NULL)
    {
        if(hp->data == x) return &hp->data;
        hp = hp->next; 
    }
    return NULL; 
} 
/* 8.把单链表中第pos个节点的值修改为x,若修改成功返回1,否则返回0*/
int updataPosList(struct sNode *hp, int pos, elemType x)
{
    int size = sizeList(hp);

    if(pos<1 && pos>size)
    {
        printf("pos位置越界.\n");
        return 0; 
    }

    int i = 1;
    while(i!=pos)
    {
        i+=1;
        hp=hp->next; 
    } 
    hp->data = x;
 
    return 1; 
} 
/* 9.向单链表的表头插入一个元素x */
void insertFirstList(struct sNode **hp, elemType x)
{
    struct sNode *newN;
    newN = malloc(sizeof(struct sNode));
    if(newN == NULL)
    {
        printf("创建新节点失败\n");
        exit(1); 
    }

    newN->data = x;
    newN->next = *hp;
    *hp = newN;
    
    return; 
} 
/* 10.向单链表的末尾添加一个元素x */
void insertLastList(struct sNode **hp, elemType x)
{
    struct sNode *newN;
    newN = malloc(sizeof(struct sNode));
    if(newN == NULL)
    {
        printf("创建新节点失败\n");
        exit(1); 
    }
    newN->data = x;
    newN->next = NULL;
 
    struct sNode *temp = *hp;
    
    if(temp == NULL)
    {
        *hp = newN;
        return;    
    } 
    while(temp->next != NULL)
    {
        temp = temp->next; 
    }
    temp->next = newN;

    return;     
} 
/* 11.向单链表中第pos个节点位置插入元素x,成功返回1,否则返回0 */
int insertPosList(struct sNode **hp, int pos, elemType x)
{
    /*判断pos位置*/ 
    int size = sizeList(*hp);

    if(pos<1 && pos>size)
    {
        printf("pos位置越界.\n");
        return 0; 
    }
    if(pos==1 && pos==size)
    {
        printf("请使用头插或尾插方法.\n");
        return 0; 
    } 
    
    /*创建新节点*/ 
    struct sNode *newN;
    newN = malloc(sizeof(struct sNode));
    if(newN == NULL)
    {
        printf("创建新节点失败\n");
        exit(1); 
    }
    newN->data = x;
    
    /*定位到pos位置的前一个节点*/ 
    int i = 1;
    struct sNode *temp = *hp; 
    while(i!=pos-1)
    {
        i+=1;
        temp=temp->next; 
    }

    /*插入*/ 
    newN->next = temp->next;
    temp->next = newN; 

    return 1; 
} 
/* 12.向有序单链表中插入元素x,使得插入后仍然有序 */
void insertOrderList(struct sNode **hp, elemType x) 
{
    /*若单链表为空*/ 
    if(*hp==NULL)
    {
        insertFirstList(hp,x);
        return; 
    }
    struct sNode *temp = *hp;
    while(1)
    {
        if(temp->next == NULL)
        {
            if(temp->data < x)
            {
                insertLastList(hp,x);
                return; 
            }else{
                insertFirstList(hp,x);
                return;        
            } 
        } 
        if(temp->next->data > x)
        {
            break; 
        }else{ 
            temp = temp->next;
        } 
    }
    /*创建新节点*/ 
    struct sNode *newN;
    newN = malloc(sizeof(struct sNode));
    if(newN == NULL)
    {
        printf("创建新节点失败\n");
        exit(1); 
    }
    newN->data = x;
    /*执行插入*/ 
    newN->next=temp->next; 
    temp->next=newN;
    
    return; 
} 
/* 13.从单链表中删除表头节点,并把该节点的值返回,若删除失败则停止运行 */
elemType deleteFirstList(struct sNode **hp)
{
    if(*hp == NULL) exit(1);

    struct sNode *temp = *hp;
    elemType data; 
    *hp = temp->next;
    data = temp->data;  
    free(temp); 
     
    return data; 
} 
/* 14.从单链表中删除表尾节点并返回它的值,若删除失败则停止运行 */ 
elemType deleteLastList(struct sNode **hp)
{
    if(*hp == NULL) exit(1);

    struct sNode *temp = *hp;
    struct sNode *next = *hp; 
    elemType data;
    
    while(next->next != NULL)
    {
        temp = next; 
        next = next->next; 
    }
    data = next->data;     

   if(next == *hp)
   {
     *hp = NULL;
   }else{
     temp->next = NULL;

   }

    free(next);

return data;      
}   
 
/* 15.从单链表中删除第pos个节点,返回其值,若删除失败则停止运行 */
elemType deletePosList(struct sNode **hp, int pos)
{
    if(*hp == NULL) exit(1);
    
        /*判断pos位置*/ 
    int size = sizeList(*hp);

    if(pos<1 && pos>size)
    {
        printf("pos位置越界.\n");
        exit(1); 
    }
    if(pos==1 && pos==size)
    {
        printf("请使用头删或尾删方法.\n");
        exit(1); 
    } 

    struct sNode *temp = *hp;
    struct sNode *next; 
    elemType data;
    
    int i = 1;

    while(i != pos-1)
    {
        i += 1;
        temp = temp->next; 
    }
    next = temp->next;
    data = next->data; 
    temp->next = next->next;
    free(next); 
    
    return data; 
}
 
/* 16.从单链表中删除值为x的第一个节点,若删除成功则返回1,否则返回0 */
int deleteValudeList(struct sNode **hp, elemType x) 
{
    if(*hp == NULL)
    {
        printf("单链表空\n"); 
        return 0; 
    }

    struct sNode *temp = *hp;
    struct sNode *next = *hp;

    while(next != NULL)
    {
        if(next->data == x)
        {
            break; 
        }else{
            temp = next;
            next = next->next; 
        } 
    }
    if(next == NULL)
    {
        printf("链表中无值为x的节点.\n");
        return 0; 
    }else{
        temp->next = next->next;
        free(next);
        return 1; 
    } 
     
} 
/* 17.删除单链表中所有为x的节点 */ 
void deleteSameList(struct sNode **hp, elemType x)
{
    if(*hp == NULL)
    {
        printf("单链表空\n"); 
        return; 
    }

    struct sNode *temp = *hp;
    struct sNode *next = *hp;

     
again:
    /*若刚好为第一个节点,由于此时temp,next指针位置相同,并不常规化,所以特殊处理.*/
    if(temp->data == x)
    {
        next = temp->next;
        *hp = temp->next;
        free(temp);
        temp = *hp;
        goto again;    
    }
 
    /*当前节点不为空*/ 
    while(next != NULL)
    {  /*当前节点data = x,跳出*/ 
        if(next->data == x)
        {
            break;  
        }else{
            /*保存当前节点位置,next指向下一个节点*/ 
            temp = next;
            next = next->next; 
        } 
    }
    /*若果next指向链表尾null,表示无与x相同节点*/ 
    if(next == NULL)
    {
        return; 
    }else{/*有与x相同节点*/  
        temp->next = next->next;
        free(next);
        next = temp->next; 
        goto again;  
    } 
} 
/* 18.去除单链表中重复的元素,保留第一个 */ 
void deleteRepeatList(struct sNode **hp)
{
    struct sNode *temp = *hp;
    elemType data; 
    while(temp != NULL)
    {
        data = temp->data; 
        temp=temp->next;
        deleteSameList(&temp,data);
    } 
} 

/***************************************************/ 
int main(void)
{
    struct sNode *hp;
#if 1  
    initList(&hp);
    insertLastList(&hp,1); 
    insertFirstList(&hp,2);
    insertLastList(&hp,3);
    insertLastList(&hp,2);
    insertLastList(&hp,5);
    insertLastList(&hp,3);
    insertLastList(&hp,6);
    insertLastList(&hp,7);
    insertLastList(&hp,1);
    insertLastList(&hp,2);
    insertLastList(&hp,2);
    insertPosList(&hp,10,2);
    /*2 1 3 2 5 3 6 7 1 2 2 2  size = 12 */ 
    travelList(hp);
    printf("size = %d\n",sizeList(hp)); 
#endif

#if 1 
    printf("删除最后一个节点...\n删除第8个节点...\n删除第一个节点...\n"); 
    deleteLastList(&hp);
    deletePosList(&hp,8);
    deleteFirstList(&hp); 
    travelList(hp);
    printf("size = %d\n",sizeList(hp)); 
#endif

#if 0
    elemType *data = findList(hp,6); 
    printf("查找 6 是否在链表中...结果:%d\n",*data);
    printf("取得链表中得第5个元素...结果:%d\n",getElem(hp,5)); 
    printf("清空链表\n"); 
    clearList(&hp);
    travelList(hp);
    printf("size = %d\n",sizeList(hp));  
#endif 

#if 1 
    printf("删除链表中所有的1....\n"); 
    deleteSameList(&hp, 1);
    travelList(hp);
    printf("size = %d\n",sizeList(hp));
#endif 

#if 1  
    printf("去除链表中得重复元素...\n"); 
    deleteRepeatList(&hp);
    travelList(hp);
    printf("size = %d\n",sizeList(hp)); 
#endif 
 
    system("pause"); 
    return 0;    
} 

************************************************************

运行结果:

************************************************************

2 1 3 2 5 3 6 7 1 2 2 2
size = 12
删除最后一个节点...
删除第8个节点...
删除第一个节点...
1 3 2 5 3 6 1 2 2
size = 9
删除链表中所有的1....
3 2 5 3 6 2 2
size = 7
去除链表中得重复元素...
单链表空
3 2 5 6
size = 4
请按任意键继续. . .

posted on 2012-06-30 00:55  尼古拉斯豆  阅读(202)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3