数据结构----线性表的应用

一.实验目的

    熟悉线性表的链式存储结构,熟练掌握线性表各种基本操作的实现,培养灵活运用线性表解决实际问题的能力。

二.实验题目

键盘输入一组元素,建立一个带头结点的单向链表(无序),遍历单向链表,在单向链表中删除元素E,然后将单向链表逆置,设计一个MAIN()函数,分别调试上述算法

对于单向链表的建立可以有两种方式选择,一种是从头结点后面依次插入,一种是从尾结点后面依次插入,可以根据实际需要选择这两种方法之一实现。

单向链表的逆置要求不增加新的存储空间,只是在原来已有链表的基础上进行逆置,而不是构造一个新的链表,将元素逆向插入到新的链表实现逆置功能。

三.实现提示

1. 数据的存储结构选择链表,链表的每个结点的定义如下。

[cpp]  view plain  copy
  1. typedef int ElemType;  
  2.  typedef struct LNode{  
  3.  ElemType data;  
  4.  struct LNode *next;  
  5.  }LNode, *LinkList;  

2. 线性链表的逆置操作可以参照下图,本图给出了一个结点逆置的过程,至少需要两个中间指针完成这个工作:


 四.思考及选做

1.如何使用顺序表实现本实验提出的要求。

2.比较顺序表和单向链表的优缺点。

3.线性链表的逆置如何能拿递归算法实现。

五.实现

[cpp]  view plain  copy
  1. #include<stdio.h>  
  2.  #include<stdlib.h>  
  3.   
  4.    
  5.  /* 
  6.     数据结构定义 
  7.  */  
  8.  typedef int ElemType;  
  9.  typedef struct LNode  
  10.  {  
  11.     ElemType data;  
  12.     struct LNode *next;  
  13.  }LNode, *LinkList;  
  14.    
  15.  /* 
  16.     创建链表 
  17.  */  
  18.  LNode * creat(LNode *head)  
  19.  {  
  20.     int n = 0;  
  21.     LNode *p1, *p2;  
  22.     p1 = p2 = (LNode *)malloc(sizeof(LNode));  
  23.     if(p1 == NULL)  
  24.     {  
  25.         printf("分配存储空间失败!");  
  26.         return 0;  
  27.     }  
  28.     printf("请输入整数,输入0结束:\n");  
  29.     scanf("%d", &(p1->data));  
  30.     while(p1->data != 0)  
  31.     {  
  32.         n++;  
  33.         if(n == 1)  
  34.         {  
  35.             head->next = p1;  
  36.         }  
  37.         else  
  38.         {  
  39.             p2->next = p1;  
  40.             p2 = p1;  
  41.         }  
  42.           
  43.         p1 = (LNode *)malloc(sizeof(LNode));  
  44.         if(p1 == NULL)  
  45.         {  
  46.             printf("分配存储空间失败1!");  
  47.             exit(1);  
  48.         }  
  49.         scanf("%d", &(p1->data));  
  50.     }  
  51.     p2->next = NULL;  
  52.     return head;  
  53.  }  
  54.    
  55.  /* 
  56.     删除表中第i个元素 
  57.  */  
  58.  LNode * DeleteList(LNode *L,int i)  
  59.  {  
  60.     LNode *p=L,*q;  
  61.     ElemType e;  
  62.     int j=0;  
  63.     //遍历线性表L,找到第i个节点,并让p指向他的前驱  
  64.     while(p->next&&j<i-1)  
  65.     {  
  66.         p=p->next;  
  67.         ++j;  
  68.     }  
  69.     //判断找的p的位置是否合理  
  70.     //if(!(p->next)||j>i-1)return -1;  
  71.     q=p->next;  
  72.     p->next=q->next;  
  73.     e=q->data;  
  74.     printf("删除的是第%d个元素%d\n",i,e);  
  75.     free(q);  
  76.     return p;  
  77.  }  
  78.    
  79.  /* 
  80.     将链表反序。 
  81.  */  
  82.  LNode * reverseOrderList(LNode *head)  
  83.  {  
  84.     LNode *p1, *p2, *p3, *p4;  
  85.     p4 = head;  
  86.     p1 = head->next;  
  87.     p2 = p1->next;  
  88.     p3 = p2->next;  
  89.     for( ; p3 != NULL; )  
  90.     {  
  91.         if(p3->next == NULL)  
  92.         {  
  93.             p3->next = NULL;  
  94.         }  
  95.         p2->next = p1;  
  96.         p1 = p2;  
  97.         p2 = p3;  
  98.         p3 = p3->next;  
  99.     }  
  100.     p2->next = p1;  
  101.     p1 = p2;  
  102.     p4->next->next = NULL;  
  103.     p4->next = p1;  
  104.     return (p4);  
  105.  }  
  106.    
  107.  /* 
  108.     打印输出链表 
  109.  */  
  110.  void print(LNode *d)  
  111.  {  
  112.     LNode *p;  
  113.     p = d->next;  
  114.     for(;p != NULL;p = p->next)  
  115.     {  
  116.         printf("%d  ", p->data);  
  117.     }  
  118.     printf("\n");  
  119.  }  
  120.    
  121.  /* 
  122.     main函数 
  123.  */  
  124.  int main()  
  125.  {  
  126.     LNode data, *head;  
  127.     LNode *h;  
  128.     //创建  
  129.     head = creat(&data);  
  130.     //删除第一个  
  131.     DeleteList(head,0);  
  132.     print(head);  
  133.     //反序  
  134.     h = reverseOrderList(head);  
  135.     print(h);  
  136.    
  137.     return 0;  
  138.  }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值