数据结构基础(C语言)--链序表

1. 完成单链表的如下设计:

抽象方法包括:

单链表的整表创建。

单链表的第i个位置插入元素。

单链表的第i个位置删除元素。

单链表的按值查询。

单链表的整表输出。

单链表的整表删除。

主函数中需要调用以上方法以演示运行结果。

代码实现:

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

#define OK 1
#define ERROR -1
#define MAX_SIZE 100
typedef int ElemType;
typedef int Ststus;

//1.链表的构建
typedef struct Lnode
{
    ElemType data;//数据域,保存节点值
    struct Lnode *next;//指针域
}LNode;//节点类型

LNode *create_LinkList()
{
    int data;
    LNode *p,*q,*head;
    head=p=(LNode*)malloc(sizeof(LNode));//创建头文件 
    head->next=NULL;//头文件指针域为空 
    printf("请输入数字(空格间隔),终止输入请按999\n");
    while(1)
    {
        scanf("%d",&data);//循环取值 
        if(data==999)//设定999为结束符号 
            {
                printf("已停止输入\n");
                break;//取值结束跳出循环 
            }
        else
        {
            q=(LNode*)malloc(sizeof(LNode));//创建新节点 
            q->next=NULL;//设定新节点指针域为空 
        }
        q->data=data;//向新节点赋值 
        q->next=p->next;
        p->next=q;//尾插法链接节点 
        p=q;//指针后移 
    }
return (head);//返回头指针 
}

//2.获得第i个节点的数值
ElemType Get_Elem(LNode *L,int i)//返回 ElemType类型的值 
{
    int j=1;
    ElemType m=-256; 
    LNode *p;
    p=L->next;//头指针中数据域无数据 
    while(p!=NULL && j<i)//循环判断是否为空,并且是否到达指定位置 
    {
        p=p->next;
        j++;
    }
    if(j==i)
        return (p->data);//返回相应的值 
    else
        return m;
}

//3.通过数值来查找节点序号
LNode *Locate_Node(LNode *L,int key)
{
    LNode *p;
    int i=1;
    p=L->next;//头指针中数据域无数据 
    while(p->next!=NULL&&p->data!=key)//判断是否为空,是否找到数值对应节点 
    {
    	i++;
      	p=p->next;
    } 

    if(p->data==key)
    {
    	printf("已找到该数值\n");
    	printf("是第%d个节点\n",i);//找到节点,输出节点的位置 (序号) 
        return p;
    }
    else
    {
        printf("未找到该数值\n");
        return (NULL);
    }
}

//4.链表的插入
void  Insert_LNode(LNode *L,int loc,ElemType e)
// 在以L为头结点的单链表的第i个位置插入值为e的结点
{
    int j=0;
    LNode *p=L;
    while(p->next!=NULL && j<loc-1)//循环判断是否为空,并且是否到达指定位置 
    {
        p=p->next;
        j++;
    }
    if(j==loc-1)
    {
    LNode *q=(LNode *)malloc(sizeof(LNode));//构建新的节点 
	q->data = e;//对新节点赋值 
	q->next = p->next;//新节点连接上链表 
	p->next = q;
    }
}
//5.删除序号节点 
void Delelte_serial(LNode *L,ElemType a)
{
	LNode *p,*q;
	ElemType i=1;
	p=q=L;
	while(i!=a)//判断是否找到相应位置 
	{
		q=q->next;
		i++;
	}
	p=q;
	q=q->next;
	p->next=q->next;//将链表连接上(将q节点跳过,便于释放) 
	free(q);//释放节点 
}
//6.删除重复节点
void Delete_Node_value(LNode *L)
{
    LNode *p,*q,*ptr;
    p = L->next;
    while(p != NULL)    // p用于遍历链表
    {
        q = p;
        while(q->next != NULL) // q遍历p后面的结点与p数值比较
        {
            if(q->next->data == p->data)
            {
                ptr = q->next; // ptr保存需要删掉的结点
                q->next = ptr->next;   // 需要删掉的结点的前后结点钩链 
                free(ptr);//释放掉ptr指向的节点 
            }
            else
                q = q->next;//q指向下一个节点 
        }
        p = p->next;//q指向下一个节点 
    }
}

//7.两个链表的合并
LNode  *Merge_LinkList(LNode *p, LNode *q)
{
    LNode *La,*Lb,*Lc,*Ld,*ptr;
    Ld=ptr=(LNode*)malloc(sizeof(LNode));
	ptr->next=NULL;
	La=p->next;
	Lb=q->next;

	while(La!=NULL && Lb!=NULL) 
	{
	  	Lc=(LNode*)malloc(sizeof(LNode));
		Lc->next=NULL;
		ptr->next=Lc;
		ptr=ptr->next; 
	    if(La->data<Lb->data)
	    {
		    Lc->data=La->data;
		    La=La->next;
	    }
	    else if(La->data==Lb->data)
		{
		    Lc->data=La->data;
	        La=La->next;
		    Lb=Lb->next;
		}
		else
		{
	        Lc->data=Lb->data;
	        Lb=Lb->next;
		}
	}
	if(La==NULL)
		while(Lb!=NULL)
		{
			Lc=(LNode*)malloc(sizeof(LNode));
		    Lc->next=NULL;
		    ptr->next=Lc;
		    ptr=ptr->next; 
		    
	        Lc->data=Lb->data;
			Lb=Lb->next;
		}
	else
		while(La!=NULL)
		{
			Lc=(LNode*)malloc(sizeof(LNode));
			Lc->next=NULL;
			ptr->next=Lc;
			ptr=ptr->next; 
			
			Lc->data=La->data;
			La=La->next;
		}
	
	return Ld;
}

//8.遍历链表仅仅用于检测
void Bianli(LNode *p)
{
  p=p->next;
  while(p!=NULL)
  {
    printf("%d  ",p->data);
    p=p->next;
  }
  printf("OK\n");
}
//9.释放三个链表
LNode * Frees(LNode *p)
{
	LNode *q;
	while(p!=NULL)
	{
		q=p->next;//先钩链再释放 
        free(p);
        p=q;
	}
	printf("OK\n");
}

//10.循环输出菜单栏,防止清屏后没有指示
void printf0()
{
	    printf("****************************************************\n");
        printf("1.链表的构建\n");
        printf("2.通过序号查询节点数值\n");
        printf("3.通过序号插入节点数值\n");
        printf("4.通过数值查找节点序号\n");
        printf("5.删除序号节点\n");
        printf("6.删除重复节点\n");
        printf("7.第二个链表的构建以及链表的合并 \n");
        printf("8.遍历三个链表\n");
        printf("9.释放三个链表\n");
        printf("0.退出\n");
        printf("****************************************************\n");
}

int main()
{
	LNode *p,*q,*ptr;
    int i,j,a;
    printf0(); 
    do
    { 
        printf("\n请输入选择的指令:\n");
		scanf("%d",&a);//输入菜单指令
        switch(a)
          {
            case 1:
					{//1.链表的构建
				 	 p=create_LinkList();
					}
					break;
            case 2:
                   {//2.通过序号查询节点数值 
	                printf("请输入需要查询的节点:\n");
					scanf("%d",&i);
					j=Get_Elem(p,i);
					printf("第%d个节点的数值为%d\n",i,j);
                   }
                    break;

            case 3:
                   {//3.通过序号插入节点数值 
					printf("请输入需要插入的节点位置以及数值:\n");
					scanf("%d",&i);
					scanf("%d",&j);
					Insert_LNode(p,i,j);
                   }
                    break;
            case 4:
                   {//4.通过数值查找节点序号 
					printf("请输入需要查询的值:\n");
					scanf("%d",&i);
					q=Locate_Node(p,i);
                   }
                    break;
           case 5:
                   {//5.删除序号节点  
					printf("请输入需要删除节点的序号:\n");
					scanf("%d",&i);
					Delelte_serial(p,i);
                   }
                    break;
            case 6:
                   {//6.删除重复节点
					printf("删除重复节点:\n原链表:");
					Bianli(p);
					Delete_Node_value(p);
					printf("已删除重复节点\n链表:");
					Bianli(p);
                   }
                    break;

            case 7:
                   {//7.第二个链表的构建以及链表的合并   
					printf("第二个链表构建:\n");
					q=create_LinkList();
					ptr=Merge_LinkList(p,q);	  	
                   }
                    break;
            case 8:
                   {//8.遍历三个链表
                    printf("第一个链表:\n");
					Bianli(p);
					printf("第二个链表:\n");
					Bianli(q); 
					printf("第三个链表:\n");
					Bianli(ptr); 
                   }
                    break;
            case 9:
                   {//9.释放三个链表
                    printf("第一个链表\n");
					Frees(p);
					printf("第二个链表\n");
					Frees(q);
					printf("第三个链表\n");
					Frees(ptr);
                   }
                    break;
            case 0:
                   {
                    printf("谢谢使用我的程序\n");
                   }
                    break;
            default:
                   {
                   printf("输入错误,请重新输入\n");
                   system("pause");
                   }
                    break;
          }
     }while(a!=0);
}

 结果如下:

数据结构基础(C语言)--链序表

数据结构基础(C语言)--链序表 

 

上一篇:线性表——链表删除


下一篇:Oracle nal() 和count(*)的注意点