数据结构【C语言】【不完全】

线性表

顺序表

定义

#define LIST_INIT_SIZE 10                  
#define LISTINCREMENT 2                 
typedef  struct
{
           ElemType  *elem;
    int  length;
    int  listsize;
}SqList;

也可以使用顺序表静态分配数组,其存储结构定义如下:

#define	MAXSIZE  100  
typedef  struct
{
    
	ElemType  elem[MAXSIZE];  
	int   last;/*记录线性表中最后一个元素在数组elem[ ]中的位置(下标值),空表置为-1*/
}SqList;

注意:静态数组或动态数组都可以实现顺序表。如果不加特殊说明,本书中采用的都是动态数组。

#include"public1.H"
#include"p2.H"
Status InitList(SqList &L)
{
    //构造一个空的顺序表
   L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
   if(!L.elem)
       exit(OVERFLOW);
   L.length=0;
   L.listsize=LIST_INIT_SIZE;
   return OK;
}
Status DestroyList(SqList &L)
{
    //销毁顺序线性表L
   free(L.elem);
   L.elem=NULL;
   L.length=L.listsize=0;
   return OK;
}
int LocateElem(SqList L, ElemType e)
{
    //根据数据元素的值,返回它在线性表L中的位置
   int i=1;
   while ((i<=L.length)&&(*(L.elem+i-1)!=e))
   	i++;
   if (i<=L.length)
   	return i;
   else
   	return(0);
}
Status GetElem(SqList L,int i,ElemType &e)
{
    //根据数据元素在线性表L中的位置,返回它的值
   if(i<0||i>L.length)
       return ERROR;
   e=*(L.elem+i-1);
   return OK;
}
Status ListInsert(SqList &L,int i,ElemType e)
{
    // 在L中第i个位置之前插入新的数据元素e,L的长度加1
   if(i>=L.listsize)
   {
   
   if(!(L.elem=(ElemType*)realloc(L.elem,sizeof(ElemType)*LISTINCREMENT)))
           exit(OVERFLOW);
       L.listsize+=LISTINCREMENT;
   }
   if(i<0)
       return ERROR;
   for(int j=L.length;j>=i;j--)
   {
   
       *(L.elem+j)=*(L.elem+j-1);
   }
   *(L.elem+i-1)=e;
   L.length++;
   return OK;
}
Status ListDelete(SqList &L,int i,ElemType &e)
{
    //删除L的第i个数据元素,并用e返回其值,L的长度减1
   if(i<0||i>L.length)
       return ERROR;
   e=*(L.elem+i-1);
   for(int j=i;j<L.length;j++)
   {
           *(L.elem+j-1)=*(L.elem+j);
   }
   L.length--;
return OK;
}
Status PriorElem(SqList L,ElemType cur_e,ElemType &pre_e)
{
    // 若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败
   int location=LocateElem(L,cur_e);
   if((!location)||cur_e==*(L.elem))
       return ERROR;
   pre_e=*(L.elem+location-2);
   return OK;
}
Status visit(SqList L)
{
    //按序输出顺序表的各个元素值
  int i;
  for(i=1;i<=L.length;i++)
    printf("%d ",*(L.elem+i-1));
  printf("L.elem=%u L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize);
  return OK;
}
int main()
{
   
  SqList L;
  ElemType e,pre_elem;
  Status i;
  int j;
  i=InitList(L);
  visit(L);
  for(j=1;j<=5;j++)
    i=ListInsert(L,1,j);
  printf("在L的表头依次插入1~5后:*L.elem=");
  visit(L);
  for(j=1;j<=5;j++)
    *(L.elem+L.length+j-1)=j;
  printf("在L的表尾依次插入1~5后:*L.elem=");
  L.length=L.length+5;
  visit(L);
  ListInsert(L,1,0);
  printf("在L的表头插入0后:*L.elem=");
  visit(L);
  i=LocateElem(L,1);
  printf("值为1的数据元素在顺序表中的位置是");
  printf("%d ",i);
  printf("\n");
  GetElem(L,5,e);
  printf("第5个元素的值为:%d\n",e);
  printf("在L中删除第三个数据元素:*L.elem=");
  ListDelete(L,3,e);
  visit(L);
  printf("第五个元素的值为:%d",*(L.elem+4));
  if(PriorElem(L,*(L.elem+4),pre_elem))
       printf(",它的前驱为:%d\n",pre_elem);
   else
       printf(",你输入的是第一个数,它没有前驱!\n");
  DestroyList(L);
  printf("销毁L后:L.elem=%u L.length=%d L.listsize=%d\n",L.elem,L.length,L.listsize);
  return 0;
}

单链表

单链表存储结构定义

typedef int ElemType;
typedef struct LNode
 {
        ElemType data;
       LNode *next;
 }LNode;
 typedef  LNode  *LinkList;       

函数部分:

#include"public1.H"
#include"p3.h"
Status InitList(LinkList &L)
 {
    // 构造一个空的单链表L
   L=(LinkList)malloc(sizeof(LNode));
   if (!L)
     exit(OVERFLOW);
   L->next=NULL;
   return OK;
 }
Status DestroyList(LinkList &L)
 {
    // 销毁单链表L
    LinkList p;
    while(p=L->next)
    {
   
        L->next=p->next;
        free(p);
    }
	return OK;
 }
void CreateList(LinkList &L,int n)
 {
    // 逆位序输入n个元素的值,建立带表头结构的单链线性表L
   int i;
   LinkList p;
   L=(LinkList)malloc(sizeof(LNode));
   L->next=NULL;
   printf("请输入%d个数据:",n);
   for(i=n;i>0;--i)
   {
   
     p=(LinkList)malloc(sizeof(LNode));
     scanf("%d",&p->data);
     p->next=L->next;
     L->next=p;
   }
 }
void CreateList2(LinkList &L,int n)
 {
    // 正位序输入n个元素的值,建立带表头结构的单链线性表
    int i;
    LinkList p,tail;
    tail=L=(LinkList)malloc(sizeof(LNode));
    L->next=NULL;
    printf("请输入%d个数据:", n);
    for(i=0;i<n;i++)
    {
   
        p=(LinkList)malloc(sizeof(LNode));
        scanf("%d", &p->data);
        p->next=NULL;
        tail->next=p;
        tail=p;
    }
 }
int ListLength(LinkList L)
 {
    // 返回L中数据元素个数
    int num=0;
    LinkList p=L->next;
    while(p)
    {
   
        num++;
        p=p->next;
    }
	return num;
 }
Status GetElem(LinkList L,int i,ElemType &e)
 {
    // L为带头结点的单链表的头指针。当第i个元素存在时,其值赋给e并返回OK,否则返回 ERROR
   int j=1;
   LinkList p=L->next;
   while(p&&j<i)
   {
   
     p=p->next;
     j++;
   }
   if(!p||j>i)
     return ERROR;
   e=p->data;
   return OK;
 }
int LocateElem(LinkList L,ElemType e)
 {
    // 返回L中第1个值为e 的数据元素的位序,若这样的数据元素不存在,则返回值为0
    LinkList p=L->next;
    int num=0;
    while(p)
    {
   
        num++;
        if(p->data==e)
            return num;
        else
            p=p->next;
    }
	return 0;
 }
Status visit(LinkList L)
 {
    //按序输出单链表的各个元素值
   LinkList p=L->next;
   while(p)
   {
   
     printf("%d ",p->data);
     p=p->next;
   }
   printf("\n");
   return OK;
 }
 Status ReverseVisit(LinkList L)
 {
   //逆位序输出单链表的各个元素的值
     LinkList p=L->next,tail;
     int length=ListLength(L);
     while(length)
     {
   
         int num=0;
         p=L->next;         //两行代码应该放在循环内部,进行初始化
         while(p&&num!=length)
         {
   //找到尾结点
             num++;
             tail=p;
             p=p->next;
         }
         printf("%d  ",tail->data);
         length--;
     }
     return OK;
 }
 Status ListInsert(LinkList &L,int i,ElemType e)
{
   //在带头节点的单链表L中第i个位置之前插入元素e
    if(i<0) return ERROR;
    int count=1;
    LinkList p=L->next,pre=L,q;
    for(    ;p&&count!=i;count++,p=(pre=p)->next);//找到第i个位置及其pre的指针
    if(count>i)  return ERROR;   //没有找到第i个位置
    q=(LinkList)malloc(sizeof(LNode));   //创建一个新的结点存放元素e
    if(!q)  exit(OVERFLOW);
    q->data=e;
    pre->next=q;
    q->next=p;
	return OK;
}

Status ListDelete(LinkList &L,int i,ElemType& e)
{
   //在带头节点的单链表L中,删除第i个元素,并由e返回其值
    if(i<0) return ERROR;
    int count=1;
    LinkList pre=L,p=L->next;
for(    ;p&&count!=i;count++,p=(pre=p)->next);  
//find i_th node and its previous node
    if(count>i) return ERROR;
    e=p->data;
    pre->next=p->next;
    free(p);
	return OK;
}
void MergeList(LinkList &La, LinkList &Lb, LinkList &Lc)
{
    //已知线性表La和Lb中的数据元素按值非递减排列
  //归并La和Lb得到新的线性表Lc,Lc的数据元素也按值非递减排列
    Lc=(LinkList)malloc(sizeof(LNode));
    LinkList pa=La->next,pb=Lb->next,pc=Lc;
    while(pa&&pb)
    {
   //到La,Lb两个表其中一个结束为止,将元素按非递减插入链表Lc中
        if(pa->data<pb->data)
            pa=(pc=pc->next=pa)->next;
        else if(pa->data>pb->data)
            pb=(pc=pc->next=pb)->next;
        else
        {
   
            pc=pc->next=pa;
            pa=pa->next;
            pc=pc->next=pb;
            pb=pb->next;
        }
    }
    while(pa&&!pb)  //Lb表结束
        pa=(pc=pc->next=pa)->next;
    while(pb&&!pa)  //La表结束
        pb=(pc=pc->next=pb)->next;
    pc->next=NULL;  //将Lc表尾部置空
}
//实现归并算法MergeList2,使重复的元素只保存一次
void MergeList2(LinkList &La,LinkList &Lb,LinkList &Lc)
{
    //已知线性表La和Lb中的数据元素按值递减排列
  //归并La和Lb得到新的线性表Lc,Lc的数据元素也按值递减排列
    Lc=(LinkList)malloc(sizeof(LNode));
    LinkList pa=La->next,pb=Lb->next,pc=Lc;
    while(pa&&pb)
    {
   //到La,Lb两个表其中一个结束为止,将元素按递减插入链表Lc中
        if(pa->data<pb->data)
            pa=(pc=pc->next=pa)->next;
        else if(pa->data>pb->data)
            pb=(pc=pc->next=pb)->next;
        else
        {
   
            pc=pc->next=pa;
            pa=pa->next;
            pb=pb->next;
        }
    }
    while(pa&&!pb)  //Lb表结束
        pa=(pc=pc->next=pa)->next;
    while(pb&&!pa)  //La表结束
        pb=(pc=pc->next=pb)->next;
    pc->next=NULL;  //将Lc表尾部置空
}

void  CreateList_L(LinkList &L,  int n){
   
	//逆位序输入n个元素的值,建立带表头结点的单链表L。
	int i;
	LinkList p;
	L=(LinkList) malloc (sizeof(LNode));
	L->next=NULL; 			//建一个带头结点的单链表
	printf("Input %d integers: ",n);
	for (i=n; i>0 ; --i )
	{
   
		p= (LinkList) malloc (sizeof(LNode)); 	//生成新结点
		scanf("%d",&p->data); 				//输入元素值
		p->next=L->next; L->next =p;		//插入到表头
	}
}// CreateList_L


void PrintList_L(LinkList L)
{
   //递归地将链表输出
    printf("%d  ",L->data);
    if(L->next) //当下一结点为空的时候,结束递归
        PrintList_L(L->next);
}

LinkList reverse(LinkList p)
{
   //递归地将单链表逆置,返回值为链表开始结点
    LinkList L,q;
    if(!p->next)    return p;   //结束递归条件,返回值为链表头结点
    L=reverse(p->next);
    p->next->next=p;
    p->next=NULL;
    return L;//返回头节点
}
int ListLength(LinkList L)
{
   //递归地求链表长度,返回值为链表长度
    if(!L->next)    return 1;
    return (ListLength(L->next)+1);
}
void ReversePrintList(LinkList L)
{
   //递归地逆序输出链表
    if(L->next)
        ReversePrintList(L->next);
    printf("%d  ",L->data);
}
LinkList MergeList(LinkList La,LinkList Lb)
{
   //递归地将两个有序链表合并,返回值为头结点
    LinkList L,p;
    if(!La) //当链表La结束时
        return Lb;
    if(!Lb) //当链表Lb结束时
        return La;
    
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值