链式线性表——课上练

链表数据结构定义及初始化链表:完成创建一个带表头的空链表的操作。

链表插入和遍历链表输出链表的操作:1.编写一个能向表尾插入结点的函数; 2.编写一个能在表头插入结点的函数; 3.编写一个能遍历链表并输出链表各结点数据元素的函数;

链表逆置:完成算法,能实现将链表中的数据元素逆置。

查找和交换:查找符合条件的结点,并将该结点的值与前驱结点的值交换。

链表销毁:完成destroyLinklist函数,实现链表结点空间的回收(链表的结点所占空间是动态分配的堆空间,程序员应在退出程序时释放动态分配的空间。)

#include <stdio.h>
#include <stdlib.h>

// 第一关代码

struct node
{
    int data;            // 存放整型数据的 data 成员
    struct node *next;   // 指向下一个结点的 next 成员
};

struct node *mycreateList()
{
    // 创建一个只有一个头结点的空链表
    // 头节点的数据域赋值为 0,并将表头结点的地址返回

    struct node *head = (struct node *)malloc(sizeof(struct node));
    if (head != NULL)
    {
        head->data = 0;
        head->next = NULL;
    }
    return head;
}

// 第二关代码

void myinsertHead(struct node *head, int insData)
{
    // 在头节点为表头的链表中进行头插数据元素 insData 的操作

    struct node *insertHead = (struct node *)malloc(sizeof(struct node));
    insertHead->data = insData;
    insertHead->next = head->next;
    head->next = insertHead;
}

void myinsertTail(struct node *head, int insData)
{
    // 在头节点为表头的单链表表尾插入数据元素 insData

    struct node *newNode = (struct node *)malloc(sizeof(struct node));
    struct node *t = head;
    newNode->data = insData;
    newNode->next = NULL;

    while (t->next != NULL)
    {
        t = t->next;
    }
    t->next = newNode;
}

void myprintList(struct node *L)
{
    // 输出头节点为表头的链表中的数据,每输出一个数据换一行

    struct node *p = L->next;
    while (p != NULL)
    {
        printf("%d\n", p->data);
        p = p->next;
    }
}

// 第三关代码

void reverseList_link(struct node *L)
{
    // 实现链表逆置功能

    struct node *p;
    struct node *q;
    p = L->next;
    L->next = NULL;
    while (p != NULL)
    {
        q = p;
        p = p->next;
        q->next = L->next;
        L->next = q;
    }
}

// 第四关代码

int locateAndChange(struct node *L, int data)
{
    // 在头结点为 L 的链表中查找与 data 值相等的第一个结点,
    // 若能找到该结点,则将该结点的值与前驱结点的值交换。
    // 若未找到与 data 值相等的结点,则返回值为 -1。
    // 若找到的结点无前驱结点,则返回值为 0,否则返回值为前驱结点的值。

    struct node *p;
    struct node *q;

    int t, a, b, flag = 0;
    p = L->next;
    while (p != NULL)
    {
        if (p->data == data)
        {
            a = p->data;
            flag = 1; // 记录是否完成查找
            break;
        }
        p = p->next;
    }
    if (flag == 0)
        return -1;
    q = L;
    while (q != NULL)
    {
        if (q->next == p)
        {
            if (q == L)
                return 0; // 排除是第一个节点
            b = q->data;
            t = a;
            a = b;
            b = t;
            return a;
        }
        q = q->next;
    }
}

// 第五关代码

int destroyList(struct node *L)
{
    // 将链表 L 的结点空间回收
    // 返回值为回收结点的个数,含头结点在内

    struct node *p;
    int count = 0;
    while (L->next)
    {
        count++;
        p = L->next;
        L->next = p->next;
        free(p);
    }
    free(L);
    return count + 1;
}

step1

int main(void)
{
	struct node *L = mycreateList();
    int a[]={1,2,3,4,5,6};
    for(int i=0;i<6;i++)
        if(i%2) myinsertTail(L,a[i]);
        else  myinsertHead(L,a[i]);
	myprintList(L);
 } 

step2

int main(void)
{
   struct node *L = mycreateList();
   if(L==NULL)
       printf("fail to create");
   else
       { printf("success to create");
         printf(" %d ",L->data); 
       }
    
    return 1;   
    
}

step3

int main(void)
 {
 	 struct node  *pllist = mycreateList() ;
 	 int num ;
	 int data;
 	 scanf("%d",&num);
 	 for(int i = 0;i < num; i++)
 	   {
 	   	  scanf("%d",&data);
 	   	  myinsertTail(pllist, data);
		}
	reverseList_link(pllist)	;
	myprintList(pllist);	
 }

step4

 int main(void)
 {
 	 struct node  *pllist = mycreateList() ;
 	 int num ;
	 int data;
     int pos ;
 	 scanf("%d",&num);
 	 for(int i = 0;i < num; i++)
 	   {
 	   	  scanf("%d",&data);
 	   	  myinsertTail(pllist, data);
		}
    scanf("%d",&data); 
	printf("%d",locateAndChange(pllist,data));
 }

step5

int main(void)
 {
 	 struct node  *pllist = mycreateList() ;
 	 int num ;
	 int data;
     int pos ;
 	 scanf("%d",&num);
 	 for(int i = 0;i < num; i++)
 	   {
 	   	  scanf("%d",&data);
 	   	  myinsertHead(pllist, data);
		}
   
	printf("%d",destroyList(pllist));
 }
 

这段代码实现了对链表的操作,包括创建链表、插入元素、输出链表数据、链表逆置、查找并交换结点值以及销毁链表等功能。

下面是每个函数的详细说明:

  1. mycreateList:创建一个只有一个头结点的空链表。头节点的数据域赋值为0,并将表头结点的地址返回。

  2. myinsertHead:在以头节点为表头的链表中进行头插数据元素的操作。创建一个新的结点,将要插入的数据赋值给新结点的数据域,然后将新结点插入到头结点之后。

  3. myinsertTail:在以头节点为表头的单链表表尾插入数据元素。创建一个新的结点,将要插入的数据赋值给新结点的数据域,然后将新结点插入到链表的尾部。

  4. myprintList:输出以头节点为表头的链表中的数据,每输出一个数据换一行。遍历链表,依次访问每个结点的数据域并打印。

  5. reverseList_link:实现链表逆置功能,将以头节点为表头的链表逆序排列。使用两个指针 pq,分别指向当前遍历到的结点和它的前一个结点,逐个修改结点的指针方向实现逆置。

  6. locateAndChange:在以头结点为表头的链表中查找与给定值相等的第一个结点。若找到该结点,则将该结点的值与前驱结点的值交换。若未找到相等的结点,则返回值为-1。若找到的结点无前驱结点(即为头结点),则返回值为0;否则返回值为前驱结点的值。

  7. destroyList:将链表的结点空间回收,销毁链表。遍历链表,依次释放每个结点的空间,并统计回收的结点个数。最后释放头结点的空间,返回回收的结点个数(包括头结点在内)。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值