数据结构线性表链表的C语言实现

                                                                                      数据结构线性表链表的C语言实现

     说明:线性表是一种最简单的线性结构,也是最基本的一种线性结构,所以它不仅是学习中的重点,也是应用开发非常常用的一种数据结构。它可以分为顺序表和链表。它的主要操作是数据元素的插入,删除,以及排序等。接下来,本篇文章将对线性链表的基本操作和运用进行详细的说明(包含在源代码的注释中),并给予可运行的程序源代码。

     线性表链表不同于顺序表,它是一种链式的线性表,和顺序表的类似数组的存储特点不同,它是一个个独立的存储单元,中间用指针链接,类似一条链子,所以叫链表。因为同属线性表所以它的基本操作与顺序表是一致的,所以基本操作函数名相同但是具体实现方式不同,顺序表的优点在于它可以随机存储数据元素,但在删除和插入操作时需要移动大量元素。而链表则相反,它无法做到随机存取,但在进行删除和插入操作时非常方便,仅需要修改下指针并释放被删除元素的存储空间而已。

     程序分析:由于抱着是程序执行起来时操作尽量简单化,使人一看就能明白,所以本程序是用了不少的提示性语句。主函数的结构是while循环和switch函数相结合的方法,使每种能够用到的基本操作尽量明白的显示在主显示函数中,这样能使每种基本操作的作用效果更加突出明了。这样不仅能使程序的模块化尽量明显,也可以让源代码的可读性增强。而且程序运用了CLS清屏函数,可以使每一次操作的输入输出结果更加清晰。

源代码:

#include<stdio.h>

#include<stdlib.h>

#include<malloc.h>

#define   OK      1

#define  ERROW   -1

#define OVERFLOW -2

#define  LEN  sizeof(struct Lnode)

#define  LN  LNode * 

typedef  int  Status;

typedef  int  ElemType;

 

/*链表的结点的数据结构 */

typedef struct Lnode

{

  ElemType num;      //为求简便数据域仅置一项 

  struct Lnode *next;

}LNode,*LinkList;     // *LinkList  L 定义链表头指针

 

/*链表的初始构建函数*/ 

Status InitList(LinkList &L)

{

   L=(LN)malloc(LEN);

   if(L==0)

   exit(OVERFLOW);

    L->next=NULL;

    return OK;

 } 

 

/*链表的清空涵数*/ 

void  ClearList(LinkList &L)

{   

    LinkList p;

   while(L->next)

 {

    p=L->next;

    L->next=p->next;

   free(p);

}

// 最终效果是只保留头节点

}

     /*销毁函数*/ 

void DestoryList(LinkList &L)

{

     ClearList(L);

     free(L); //释放头节点空间 

     L=NULL;//链表的变量归于初始值,便于识别和处理

}

 

  /*取表长函数*/

Status GetLength(LinkList L)

{

    int n;

    n=0;

    if(L==NULL)//未经初始构建函数构建或已经彻底销毁 

    return n;

   while(L->next)

  {

   L=L->next;

   n++;

 }

return n;

}

 

/*判断表的空否的函数 */ 

Status IsEmpty(LinkList L)

{

    if(L->next==NULL)

     return OK;

    else

   return ERROW;

}

 

/*定位取值函数*/

Status GetElem(LinkList L,int i,ElemType &e)

{

     int j=1;

     LinkList p;

    p=L->next;

    while(p&&j<i)

  {

       p=p->next;

      j++;

    }

  if(p==NULL||j>i)  //所给位置序号超出表长 

  {

    printf("序号输入错误!\n\n");

   return ERROW;

  }

  e=p->num;

return OK; 

}

 

/*查找定位函数*/ 

Status LocateElem(LinkList L,int &i,ElemType e)

{

      i=1;

     LinkList p;

     p=L->next;

  while(p&&p->num!=e)

 {

    p=p->next;

    i++; 

}

if(p!=NULL)

 return OK;

else

 return ERROW; 

}

 

 /*创建一个链表*/

 void ScanList(LinkList &L)

{

     int i;

    LinkList p,p0;

    if(L==NULL)

    InitList(L);

    p0=L;

   printf("请输入链表长度\n");

   scanf("%d",&i);

   printf("\n请输入%d个数\n",i);

    for(;i>0;i--) 

  {

  p=(LN)malloc(LEN);

  p->next=NULL;

  scanf("%d",&p->num);

  p0->next=p;

  p0=p;

 }

}

 

/*输出表中所有数据元素*/

void PrintList(LinkList L)

{

    LinkList p0;

    p0=L->next;

    printf("\n");

    while(p0!=NULL)

   {

       printf("%d  ",p0->num);

       p0=p0->next;

    }

printf("\n");

}

 

 /*数据元素插入函数*/

Status ListInsert(LinkList &L,int i,ElemType e)

{

   int j=0;

   LinkList p,p0;

   p=L;

  while(p&&j<i-1)

{

    p=p->next;

    j++; 

  if(p==NULL||j>i)

 {

    return ERROW;

}

  p0=(LN)malloc(LEN);

  p0->num=e;

  p0->next=p->next;

  p->next=p0;

  return OK;

}

 

/*定位删除函数*/ 

Status ListDelete_1(LinkList &L,int i)

{

    int j=0;

   LinkList p,p0;

   p=L;

  while(p&&j<i-1)

{

     p=p->next;

     j++; 

  if(p==NULL||j>i)

{

     return ERROW;

}

     p0=p->next;

     p->next=p0->next; 

     free(p0);

    return OK;

}

 

/*非递减冒泡排序函数*/ 

int maopao(LinkList &L)

{ 

     int i,j,t,n;

     LinkList p,p0;

     p0=L;

     n=GetLength(L);

   for(j=1;j<=n-1;j++)

{

      p0=p0->next;

      p=p0;

   for(i=1;i<=n-j;i++)

   {

      if(p->num>p->next->num)

     {

         t=p->num;

         p->num=p->next->num;

         p->next->num=t;

     }

    p=p->next;

 }

}

return OK;

}

 

/*主提示函数*/ 

void printlin()

{

   printf("\n");

   printf("\t\t\t线性链表基本操作学习系统\n");

   printf("\t\t\t      ***主菜单***\n\n"); 

   printf("\t\t\t    *1 创建一个链表表\n");

   printf("\t\t\t    *2 定位输出一个数据元素\n");

   printf("\t\t\t    *3 输出链表中所有元素\n");

   printf("\t\t\t    *4 定位插入一个数据元素\n");

   printf("\t\t\t    *5 定位删除一个数据元素\n");

   printf("\t\t\t    *6 定值删除一个数据元素\n"); 

   printf("\t\t\t    *7 清空链表\n");

   printf("\t\t\t    *8 销毁链表\n");

   printf("\t\t\t    *9 对表内数据元素进行非递减排序\n"); 

   printf("\t\t\t    *0 结束程序\n");

}

 

  int main()

{

          int i,j,k;

          LinkList L;

          L=NULL;

         printf("编写此程序目的是自我学习线性表链表\n");

         printlin();

   while(1)

  {

        int t;

        scanf("%d",&t);

      if(t!=0) 

         if(t==1||GetLength(L)!=0)

        {

              switch(t)

             {

                   case 1:   if(GetLength(L)!=0)

                                {

                                    printf("链表已存在,是销毁并重新创建链表?\n");

                                    printf("*1 是   *2 否\n");

                                    scanf("%d",&i);

                                      if(i==1)

                                     {

                                           DestoryList(L); 

                                           ScanList(L);

                                     }          

                                  }

                                else

                                  ScanList(L);

                                  break;

                   case 2:   {

                                    k=GetLength(L);

                                    printf("请输入数据位置\n");

                                    scanf("%d",&i);

                                    if(i<1||i>k)

                                        printf("输入位置错误\n");

                                    else 

                                     {

                                           GetElem(L,i,j);

                                            printf("第%d个数为%d\n",i,j);

                                       }

                                       break;

                                  }

                   case 3:    PrintList(L);break;                  

                   case 4:    {

                                       printf("输入要插入的位置\n");

                                       scanf("%d",&i);

                                       printf("请输入要插入的数据\n");

                                       scanf("%d",&j);

                                       k=ListInsert(L,i,j); 

                                      if(k==-1)

                                        printf("插入位置不合法,插入数据操作失败!\n\n");

                                      else 

                                        printf("插入数据成功\n\n");

                                     break;

                                 }

                   case 5:   {

                                      printf("请输入要删除数据位置\n");

                                      scanf("%d",&i);

                                       k=ListDelete_1(L,i);

                                      if(k==-1)

                                            printf("输入位置错误,删除操作失败!\n\n");

                                     else

                                         printf("删除成功!\n\n");

                                     break;

                                 }

                 case 6:   {

                                   printf("请输入需要删除的元素:\n");

                                   scanf("%d",&j);

                                   k=LocateElem(L,i,j);

                                   if(k==-1)

                                     printf("未找到该元素,删除操作失败!\n\n");

                                 else

                                  {

                                    ListDelete_1(L,i);

                                    printf("删除成功!\n\n");

                                   }

                                     break;

                              }  

                case 7:  {

                                  ClearList(L);

                                  printf("清空完毕,返回主菜单\n\n");

                                  break;

                              }

              case 8:   {

                                  DestoryList(L);

                                  printf("销毁成功,返回主菜单\n\n");

                                   break;

                             }

             case 9:    {

                               maopao(L);

                               printf("已成功排序,返回主菜单\n\n");

                               break;

                             }  

            case 0:    break;

           default:   {

                            printf("输入有误,可以重新选择,退出按0!\n\n");          

                           }

             }

         } 

        else

           printf("链表未创建或已清空或销毁,请先创建链表\n\n");

     system("pause");

    system("CLS");

     printlin();

    if(t==0)

       break;

  } 

 return 0;

}

 

程序运行效果图 (部分):

 

                         

                                                                           图 1

 

 

                         

                                                                          图2

 

                          

                                                                       图3

                           

                                                                         图4

 

 

 

 

结束语:纸上得来终觉浅,绝知此事要躬行!

时间: 2024-10-18 15:55:08

数据结构线性表链表的C语言实现的相关文章

数据结构——线性表——链表反转

链表反转有两种常见方式.下面从图中详细解释.其中带有部分核心代码,最后上完整代码. 迭代法 //首先定义三个变量    PNODE pre = NULL;    PNODE now = pHead->pNext;    PNODE next = NULL; next = now->pNext;//先保存下一个节点 now->pNext = pre;//当前节点的next指针指向前一个节点 pre = now;//前一个节点赋值为当前节点 now = next;//当前节点赋值为下一个节点

线性表--链表(PHP实现)

上一篇文章写了线性表的基本概念以及用C语言实现链表,有兴趣的同学可以看看:线性表--链表(C语言实现). 现在,我们来看看用PHP来实现链表. 我们都知道,链表由一个个结点组成.在c语言中,我们用结构来定义一个结点,那么在PHP中我们用什么来定义结点? 当然是类. <?php //用面向对象的思想定义结点 class Node { public $value; public $next = null; } 先给出创建和遍历链表的代码,我们再说说链表的插入和删除操作,比起用顺序存储结构实现线性表的

数据结构&gt;&gt;线性表【注意】--&gt;链表求A-B(原A与B都递增,求完的A-B不改变A原来的顺序)

/*关于链表的题目 * A.B是两个递增有序的单链表,元素个数分别是m和n,求 * 集合A-B,并将结果保存在A中,且仍然保持递增有序. * converge_ab */ #include <iostream.h> using namespace std; typedef struct lnode{ int data; struct lnode * next; }lnode; int main(){ lnode * create_chain(int num,int interval,int s

[考研系列之数据结构]线性表之链表

1.链表分类 通过线性表概述,我们知道了链表这样一种数据结构,它又分成三类,分别是 单向链表 循环链表 双向链表 单向链表 单向链表的指针域只有一个指向下一个节点的指针,需要注意几点: 1.头指针--指向第一个节点 2.最后一个结点的指针指向NULL 3.头结点--在链表的第一个结点之前附设一个结点,它的数据域为空 所以,我们看到:  单向链表为空的<=>链表有且只有一个头结点<=>头结点的指针指向NULL 循环链表 循环链表和单向链表最大的不同就是:最后一个结点的指针不再指向NU

《数据结构 - 线性表》链式存储 (单链表)

一:线性表定义 -<数据结构 - 线性表>顺序存储结构 二:为什么要 链式存储 线性表? - 因为在使用 顺序结构 存储方式存储的时候,每次进行 插入/删除 都需要大量移动元素的位置. - 所以设计出一种 存储空间不连续 的存储结构. - 这个线性表可能是这样的(存储位置不固定) -  三:链式存储 定义 -  因为链式存储,不是连续空间,所以需要两个信息 - 一个用于 存储数据元素,也叫做 数据域 - 一个用于 指向 下一个位置 的 指示信息,叫做指针域. - 指针域中存储的信息叫指针/链

数据结构-线性表_顺序表

进入大学一年了,今日终于有勇气写写随笔并展示出来了. 如有不足之处,请大家指正. 今日我想写的就是我对数据结构-线性表_顺序表的理解. 不BB了,进入正题!!!!! 数据结构中的逻辑结构分为线性结构和非线性结构,而线性表就属于线性结构. 线性结构是 n 个数据元素的有序(次序)集合,它有下列几个特征: 集合中必存在唯一的一个 "第一个元素": 集合中必存在唯一的一个 "最后的元素": 除最后元素之外,其它数据元素均有唯一的 "后继": 除第一元素

(续)线性表之双向链表(C语言实现)

在前文实现单向链表的基本操作下,本文实现 双向链表的基本操作. 双向链表与单链表差异,是双向链表结点中有前向指针和后向指针. 所以在插入和删除新结点元素时候不见要考虑后向指针还要考虑 前向指针. 以下是双向链表的C代码: #include<stdio.h> typedef struct node { int data; struct node *next; struct node *prior }Node; //链表的初始化 Node* InitList(int number) { int i

数据结构-线性表(2)

线性表定义: 线性表是最基本.最简单.也是最常用的一种数据结构.线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的.线性表的逻辑结构简单,便于实现和操作.因此,线性表这种数据结构在实际应用中是广泛采用的一种数据结构. 存储空间是否连续: 一.顺序表的特点是逻辑上相邻的数据元素,物理存储位置也相邻,并且,顺序表的存储空间需要预先分配. 优点: (1)方法简单,各种高级语言中都有数组,容易实现. (2)不用为表示节点间的逻辑关系而增加额外的存储开

java实现数据结构-线性表-顺序表,实现插入,查找,删除,合并功能

package 顺序表; import java.util.ArrayList; import java.util.Scanner; public class OrderList { /** * @param args * @author 刘雁冰 * @2015-1-31 21:00 */ /* * (以下所谓"位置"不是从0开始的数组下标表示法,而是从1开始的表示法.) * (如12,13,14,15,16数据中,位置2上的数据即是13) * * 利用JAVA实现数据结构-线性表-顺