zoukankan      html  css  js  c++  java
  • 数据结构与算法分析(线性表实现)

    ★线性表是一个序列(线性结构),具有一定的顺序 ★如果有多个元素,第一个元素没有前驱,最后一个元素没有后继 ★线性表强调是有限的

    一.线性表基本存储结构

    ㈠.顺序表 ——把线性表的结点按逻辑顺序依次存放在一组地址连续的存储单元里,用这种方法存储的线性表简称顺序表 ——在顺序表中,线性表的逻辑顺序与物理顺序一致 ——在顺序表中,数据元素之间的关系是以元素在计算机内“物理位置相邻”来体现

    ㈡.单链表 ——把线性表的元素任意存放在存储单元结点中,节点之间按照逻辑顺序通过一个个指针依次链接起来,用这种方式存储的线性表简称单链表 ——在单链表中,存储单元结点可以是连续的,也可以是不连续的,甚至是零散分布在内存中任意位置上的 ——在单链表中,线性表的逻辑顺序与物理顺序不一定相同 ——在单链表中,数据元素之间的关系是通过节点间的指针来实现的 1)不带头结点的单链表

    2)带头结点的单链表

    二.抽象数据类型定义

    struct list; //定义结构体作为存储的一级结构 list_init(); //初始化线性表,创建存储空间并返回指向该空间的指针 free(struct list *list); //释放内存 clear(struct list *list); //清空已定义的存储结构中的元素
    isempty(struct list *list); //判断存储结构中是否存储有数据元素 count(struct list *list); //查看存储结构中存储有多少个数据元素 add(struct list *list,int index,int e); //将数据元素存储入已定义的存储结构的指定位置 remove(struct list *list,int index); //将线性表指定位置的元素移除 get(struct list *list,int index); //将线性表指定位置的元素取出 set(struct list *list,int index,int e); //修改线性表指定位置的元素值 lookup(struct list *list,int e); //查看数据e是否存在该线性表中

    三.代码实现

    list.h

    #ifndef __LIST_H__
    #define __LIST_H__
    
    struct list;
    
    struct list *list_init();
    void list_free(struct list *list);
    
    void list_clear(struct list *list);
    int list_isempty(struct list *list);
    int list_count(struct list *list);
    
    void list_add(struct list *list,int index,int e);
    int list_remove(struct list *list,int index);
    int list_get(struct list *list,int index);
    void list_set(struct list *list,int index,int e);
    
    int list_lookup(struct list *list,int e);
    #endif
    

    main.c

    #include <stdlib.h>
    #include <stdlib.h>
    include <list.h>
    //定义两个线性表,比较两个线性表中的元素,去除两个表中重复的元素
    int main(){
      //定义指向list结构体的结构体指针变量lista/listb
      struct list *lista=NULL;
      struct list *listb=NULL;
      //初始化lista,创建线性表并把首地址赋值给lista
      lista=list_init();
      //将0存储到lista指向的线性表存储结构的0号位置处
      list_add(lista,0,0);
      //将2存储到lista指向的线性表存储结构的0号位置处,之前定义在0号位置处的数据元素0会按照.c文件中实现的算法自动移动到0号位置后面作为1号位置的元素
      list_add(lista,0,2);
      list_add(lista,0,5);
    
      listb=list_init();
      list_add(listb,0,2);
      list_add(list,0,1314);
      list_add(listb,0,5);
    
      int i,j,flag;
      //遍历listb指向的线性表存储结构
      for(i=0;i<list_count(listb);j++){
           falg=1;
          for(j=0;i<list_count(lista);j++){//遍历lista指向的线性表存储结构
          if(list_get(listb,i)==list_get(lista,j)){    //两个线性表元素对比,相同的去除
              flag=0;
              break;
          }
       }
       if(flag==1){//两表不同的元素存储(添加)到lista指向存储结构已有元素的后面
           list_add(lista,list_count(lista),list_get(listb,i));
        }
      }
      //将lista指向的存储结构的数据元素循环打印
      for(i=0;i<list_count(lista);i++){
           printf(“%d
    ”,list_get(lista,i));
      }
      
      list_free(lista);
      list_free(listb);
    
      return 0;
    }
    

    list.c

    顺序表

    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    #include "list.h"
    //定义数组初始长度为1,每次添加的长度为1
    #define LIST_INIT_SIZE 1
    #define LIST_INCR_SIZE 1
    //定义结构体list作为一级结构,指针变量bottom指向数组,count变量计算线性表中已有元素的个数,size变量计算定义的结构中数组的定义的长度
    struct list{
    	int *bottom;
    	int count;
    	int size;
    };
    
    struct list *list_init()
    {
    	struct list *list=NULL;
    	list=(struct list *)malloc(sizeof(struct list));
    	if(list==NULL)  return NULL;
    	
    	assert(list!=NULL);
    	
    	list->bottom=NULL;
    	list->count=0;
    	list->size=0;
    	
    	list->bottom=(int *)malloc(sizeof(int)*LIST_INIT_SIZE);
    	if(list->bottom==NULL){
    		free(list);
    		return NULL;
    	}
    	
    	assert(list->bottom!=NULL);
    	//将定义的存储结构中的数组空间清零
    	memset(list->bottom,0,sizeof(int)*LIST_INIT_SIZE);
    	list->size=LIST_INIT_SIZE;
    	
    	return list;
    }
    
    void list_free(struct list *list)
    {
    	assert(list->bottom!=NULL);
    	assert(list!=NULL);
    	
    	free(list->bottom);
    	free(list);
    }
    
    void list_clear(struct list *list)
    {
    	assert(list->bottom!=NULL);
    	assert(list!=NULL);
    	
    	list->count=0;
    }
    
    
    int list_isempty(struct list *list)
    {
    	assert(list->bottom!=NULL);
    	assert(list!=NULL);
    	
    	return (list->count==0);
    }
    
    int list_count(struct list *list)
    {
    	assert(list->bottom!=NULL);
    	assert(list!=NULL);
    	
    	return list->count;
    }
    
    void list_add(struct list *list,int index,int e)
    {
        assert(list->bottom!=NULL);
        assert(list!=NULL);
        //为了防止定义数组长度不够,使用realloc动态增加数组长度
        if(list->count==list->size){
        	list->bottom=(int *)realloc(list->bottom,sizeof(int)*(list->size+LIST_INCR_SIZE));
    	}
    	
    	list->size+=LIST_INCR_SIZE;
        
        int i;
        //将数据元素e添加到数组指定位置index,先将index后面的数据元素都后移一位
        for(i=list->count-1;i>index-1;i--){
        	list->bottom[i+1]=list->bottom[i];
    	}
        //将数据元素e添加到线性表存储结构index位置处	
        list->bottom[index]=e;
    	//记录线性表存储结构元素+1
    	list->count++;
    	
    	return;
    }
    
    int list_remove(struct list *list,int index)
    {
        assert(list->bottom!=NULL);
        assert(list!=NULL);
        assert(index>=0&&index<list->count);
        
        int i;
        int result=-1;
        //将线性表存储结构中数组index位置处数据元素取出
        result=list->bottom[index];
    	//将index位置后面的元素均往前一位,覆盖掉数组index位置处的值
    	for(i=index;i<list->count-1;i++){
    		list->bottom[i]=list->bottom[i+1];
    	}	
    	//记录线性表存储结构的数组元素减少一位
    	list->count--;
    	
    	return result;
    }
    
    int list_get(struct list *list,int index)
    {
    	 assert(list->bottom!=NULL);
        assert(list!=NULL);
        assert(index>=0&&index<list->count);
        
        int result=-1;
        
        result=list->bottom[index];
        
        return result;
    }
    
    void list_set(struct list *list,int index,int e)
    {
    	assert(list->bottom!=NULL);
        assert(list!=NULL);
        assert(index>=0&&index<list->count);
        
        list->bottom[index]=e;
        
        return;
    }
    
    int list_lookup(struct list *list,int e)
    {
    	int i;
    	//循环遍历数组元素并与数据元素e做比较
    	for(i=0;i<list->count;i++){
    		if(list->bottom[i]==e){ 
    	return 1;
    		} 
    	}
    	return 0;
    }
    

    单链表(不带头结点)

    #include <stdlib.h>
    #include <assert.h>
    #include <string.h>
    
    #include "list.h"
    //定义结构体作为单链表的数据节点,节点中data变量用来存储数据元素,next结构体指针变量用来存储list_node结构体变量的首地址
    struct list_node{
    	int data;
    	struct list_node *next;
    }; 
    //定义结构体作为一级结构,一级结构中head用来引用结构体list_node类型的数据节点,count用来记录单链表存储结构中一共使用的数据节点的数量
    struct list{
    	struct list_node *head;
    	int count;
    };
    
    struct list *list_init()
    {
    	struct list *list=NULL;
    	list=(struct list *)malloc(sizeof(struct list));
    	if(list==NULL)  return NULL;
    	
    	assert(list!=NULL);
    	
    	list->count=0;
    	list->head=NULL;
    	
    	return list;  
    }
    //逐级释放内存空间
    void list_free(struct list *list)
    {
    	assert(list!=NULL);
    	//定义指向list_node结构体类型的指针变量p
    	struct list_node *p=NULL;
    	//如果list引用的head变量中存储有list_node结构体类型的地址(list->head后面有数据节点),执行"断链"操作——用p指向list->head指向的元素,list->head指向该数据节点后面的节点(如果还有的话)
    	while(list->head!=NULL){
    		p=list->head;
    		list->head=p->next;
    		free(p);
    	}
    	assert(list->head==NULL);
    	
    	free(list);
    } 
    
    void list_clear(struct list *list)
    {
    	assert(list!=NULL);
    	
    	struct list_node *p=NULL;
    	//和list_free中的操作同理
    	while(list&&list->head!=NULL){
    		p=list->head;
    		list->head=p->next;
    		free(p);
    	}
    	assert(list->head==NULL);
    	
    	list->count=0;
    }
    
    int list_isempty(struct list *list)
    {
    	assert(list!=NULL);
    	
    	return (list->count==0);
    }
    
    int list_count(struct list *list)
    {
    	assert(list!=NULL);
    	
    	return list->count; 
    
    }
    
    void list_add(struct list *list,int index,int e)
    {
    	assert(list!=NULL);
    	assert(index>=0&&index<=list->count);
    	
    	int i;
    	
    	struct list_node *p=NULL;
    	//定义指向list_node结构体类型的变量p和node
    	struct list_node *node=NULL;
    	node=(struct list_node *)malloc(sizeof(struct list_node));
    	if(node==NULL){
    		perror("malloc node struct error!");
    		exit(0);
    	}
    	//将数据元素e存储到已定义的结构体中,构成数据一个数据节点
    	node->data=e;
    	node->next=NULL;
    	//如果是添加第一个数据节点,让list->head代替node指向该数据节点(将该数据节点链接到定义的单链表存储结构中)
    	if(index==0){
    		node->next=list->head;
    		list->head=node;
    		list->count++;
    		return;
    	}
            //如果并不是添加到第一个位置,将指针变量p移动,指向index位置前面的数据节点
    	p=list->head;
    	
    	for(i=0;i<index-1;i++){
    	    p=p->next;	
    	}
    	//用p->next代替node,将数据节点链接到已定义单链表存储结构上
    	node->next=p->next;
    	p->next=node;
    	list->count++;
    	
    	return;
    }
    
    int list_remove(struct list *list,int index)
    {
    	assert(list!=NULL);
    	assert(index>=0&&index<list->count);
    	
    	int i;
    	int result=-1;
    	
    	struct list_node *p=NULL;
    	struct list_node *node=NULL;
    	//移除单链表上第一个数据元素,用node代替list->node,将数据节点取出。list->node指向该节点后一个元素
    	if(index==0){
    		node=list->head;
    		list->head=node->next;
    		result=node->data;
    		list->count--;
    		
    		return result;
    	} 
    	
    	p=list->head;
    	
    	for(i=0;i<index-1;i++){
    		p=p->next;
    	}
    	
    	node=p->next;
    	p->next=node->next;
    	result=node->data;
    	list->count--;
    	
    	return result;
    }
    
    void list_set(struct list *list,int index,int e)
    {
        assert(list!=NULL);
    	assert(index>=0&&index<list->count);
    	
    	int i;
    	struct list_node *p=NULL;
    	p=list->head;
    	
    	for(i=0;i<index;i++){
    		p=p->next;
    	}
    	
    	p->data=e;
    	
    	return;	
    } 
    
    
    int list_get(struct list *list,int index)
    {
    	assert(list!=NULL);
    	assert(index>=0&&index<list->count);
    	
    	struct list_node *p=NULL;
    	p=list->head;
    	
    	int i,result=-1;
    	
    	for(i=0;i<index;i++){
    		p=p->next;
    	}
    	
    	result=p->data;
    	
    	return result;
    }
    
    int list_lookup(struct list *list,int e)
    {
    	assert(list!=NULL);
    	
    	int i;
    	
    	struct list_node *p=NULL;
    	
    	p=list->head;
    	
    	for(i=0;i<list->count;i++){
    		if(p->data==e){
    			return 1;
    			break;
    		}
    		p=p->next;
    	}
    	return 0;
    }
    

    单链表(带头结点)

    //基本原理参考不带头结点的单链表
    #include <stdlib.h>
    #include <assert.h>
    #include <string.h>
    
    #include "list.h"
    
    struct list_node{
    	int data;
    	struct list_node *next;
    };
    
    struct list{
    	struct list_node *head;
    	int count;
    };
    
    struct list *list_init()
    {
    	struct list *list=NULL;
    	list=(struct list *)malloc(sizeof(struct list));
    	if(list==NULL)  return NULL;
    	
    	assert(list!=NULL);
    	
    	list->head=NULL;
    	list->count=0;
    	
    	list->head=(struct list_node *)malloc(sizeof(struct list_node));
    	if(list->head==NULL){
    		free(list);
    		return NULL;
    	}
    	
    	assert(list->head!=NULL);
    	//定义头结点
    	list->head->data=-1;
    	list->head->next=NULL;
    	
    	return list;
    }
    
    void list_free(struct list *list)
    {
    	assert(list->head!=NULL);
    	assert(list!=NULL);
    	
    	struct list_node *p=NULL;
    	
    	while(list&&list->head!=NULL){
    		p=list->head;
    		list->head=p->next;
    		free(p);
    	}
    	assert(list->head==NULL);
    	
    	free(list);
    	
    	return;
    }
    
    void list_clear(struct list *list)
    {
    	assert(list->head!=NULL);
    	assert(list!=NULL);
    	
    	struct list_node *p=NULL;
    	
    	while(list->head->next!=NULL){
    		p=list->head->next;
    		list->head->next=p->next;
    		free(p);
    	}
    	
    	assert(list->head->next==NULL);
    	
    	list->count=0;
    }
    
    int list_isempty(struct list *list)
    {
    	assert(list->head!=NULL);
    	assert(list!=NULL);
    	
    	return (list->count==0); 
    }
    
    int list_count(struct list *list)
    {
    	assert(list->head!=NULL);
    	assert(list!=NULL);
    	
    	return list->count;
    }
    
    void list_add(struct list *list,int index,int e)
    {
    	assert(list->head!=NULL);
    	assert(list!=NULL);
    	assert(index>=0&&index<=list->count);
    	
    	int i;
    	
    	struct list_node *p=NULL;
    	struct list_node *node=NULL;
    	
    	node=(struct list_node *)malloc(sizeof(struct list_node));
    	if(node==NULL){
    		perror("malloc node struct error!
    ");
    		exit(1);
    	}
    	
    	node->data=e;
    	node->next=NULL;
    	
    	p=list->head;
    	
    	for(i=-1;i<index-1;i++){
    		p=p->next;
    	}
    	
    	node->next=p->next;
    	p->next=node;
    	list->count++;
    	
    	return;
    }
    
    int list_remove(struct list *list,int index)
    {
    	assert(list->head!=NULL);
    	assert(list!=NULL);
    	assert(index>=0&&index<list->count);
    	
    	int i;
    	int result=-1;
    	
    	struct list_node *p=NULL;
    	struct list_node *node=NULL;
    	
    	p=list->head;
    	
    	for(i=-1;i<index-1;i++){
    		p=p->next; 
    	}
    	
    	node=p->next;
    	p->next=node->next;
    	list->count--;
    	
    	result=node->data;
    	
    	return result;
    }
    
    void list_set(struct list *list,int index,int e)
    {
    	assert(list->head!=NULL);
    	assert(list!=NULL);
    	
    	struct list_node *p=NULL;
    	int i;
    	
    	p=list->head;
    	for(i=-1;i<index;i++){
    		p=p->next;
    	}
    	
    	p->data=e;
    	
    	return;
    }
    
    int list_get(struct list *list,int index)
    {
    	assert(list->head!=NULL);
    	assert(list!=NULL);
    	
    	struct list_node *p=NULL;
    	int result=-1;
    	int i;
    	
    	p=list->head;
    	
    	for(i=-1;i<index;i++){
    		p=p->next;
    	}
    	
    	result=p->data;
    	
    	return result;
    }
    
    int list_lookup(struct list *list,int e)
    {
    	assert(list->head!=NULL);
    	assert(list!=NULL);
    	
    	struct list_node *p=NULL;
    	int i;
    	
    	p=list->head;
    	
    	for(i=-1;i<list->count-1;i++){
    		p=p->next;
    		if(list->head->data==e){
    			return 1;
    			break;
    		}
    	}
            return 0; 
     }
    

    四. 编译结果

  • 相关阅读:
    【转】js竖状伸缩导航
    大学易站暂时关闭通知
    【转】神同步!这俩熊孩子太会玩了,以前的同步都弱爆了
    【技术贴】搜狗浏览器 标签页 看后吧 解决
    四级查分步骤解决无法找到对应的分数 请确认你已安装并启动了CET查分保护盾
    解决Mysql远程连接出错不允许访问 ERROR 1130:Host is not allow
    xml 获取节点下的 属性。
    Oracle 获取日期区间数据
    js 数值转换为3位逗号分隔
    xml获取子节点
  • 原文地址:https://www.cnblogs.com/miaowulj/p/12235972.html
Copyright © 2011-2022 走看看