九 哈希表、图、图的遍历

哈希(散列)表概述

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。

哈希表作为一种数据结构其实并不难,其本质就是一顺序存储的循序表。
只要牢牢抓住 M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数 在代码中的实现就行
在这里插入图片描述
哈希表是顺序存储

散列函数的设计

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package demo13;

public class StuInfo {

	private int age;
	private int count;

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public int getCount() {
		return count;
	}

	public void setCount(int count) {
		this.count = count;
	}
	
	/**
	 * 散列函数
	 */
	public int hashCode() {
		return age;
	}

	public StuInfo(int age, int count) {
		super();
		this.age = age;
		this.count = count;
	}

	public StuInfo(int age) {
		super();
		this.age = age;
	}

	@Override
	public String toString() {
		return "StuInfo [age=" + age + ", count=" + count + "]";
	}

}

===================================================================================
package demo13;

import java.util.Arrays;

public class TestHashTable {

	public static void main(String[] args) {
		StuInfo s1 = new StuInfo(16, 3);
		StuInfo s2 = new StuInfo(17, 11);
		StuInfo s3 = new StuInfo(18, 23);
		StuInfo s4 = new StuInfo(19, 24);
		StuInfo s5 = new StuInfo(20, 9);
		
		HashTable ht = new HashTable();
		ht.put(s1);
		ht.put(s2);
		ht.put(s3);
		ht.put(s4);
		ht.put(s5);

		System.out.println(ht);
		
		//想要获取的目标数据
		StuInfo target = new StuInfo(18);
		StuInfo info = ht.get(target);
		System.out.println(info);
		
	}
	
}
===================================================================================
package demo13;

import java.util.Arrays;

public class HashTable {
	private StuInfo[] data = new StuInfo[100];
	
	/**
	 * 向散列表中添加元素
	 * @param stuInfo
	 */
	public void put(StuInfo stuInfo) {
		//调用散列函数获取存储位置
		int index = stuInfo.hashCode();
		//添加元素
		data[index]=stuInfo;
	}
	
	public StuInfo get(StuInfo stuInfo) {
		return data[stuInfo.hashCode()];
	}

	@Override
	public String toString() {
		return "HashTable [data=" + Arrays.toString(data) + "]";
	}
	
	

}

散列冲突的解决方案

在这里插入图片描述
在这里插入图片描述
链地址法会更常用一些

图结构概述

图虽然作为比较难的数据结构,但是如果能把握住图中主要含有的 顶点组 和 邻接矩阵就会容易理解和使用
在这里插入图片描述

图结构代码实现

在这里插入图片描述

public class Graph {

	// 定义所有顶点
      private Vertex[] vertex;
	// 定义当前顶点多少
      public int currentSize;
	// 定义邻接矩阵
      public int[][] adjMat;
   // 图的构造函数,用于初始化
      public  Graph(int size){
      	vertex=new Vertex[size];
      	adjMat=new int[size][size];
	  }

 // 加入顶点,就是加入顶点集合里
	public void addVertex(Vertex v){
      	vertex[currentSize++]=v;
	}


    // 确定邻接矩阵,即确定边
	 public void addEdge(String v1,String v2) {
		 //找出两个顶点的下标
		 int index1=0;
		 int index2=0;
		 for(int i=0;i<vertex.length;i++){
		 	if(vertex[i].getValue().equals(v1)){
		 		index1=i;
		 		break;
			}
		 }
		 for(int i=0;i<vertex.length;i++){
			 if(vertex[i].getValue().equals(v2)){
				 index2=i;
				 break;
			 }
		 }
		 for(int i=0;i<vertex.length;i++){
			 adjMat[i][i]=1;
		 }
		 adjMat[index1][index2]=1;
		 adjMat[index2][index1]=1;
	 }
}
package demo14;

import demo2.MyStack;

/**
 * 图
 * @author Richard
 *
 */
public class Graph {

	private Vertex[] vertex;
	private int currentSize;
	public int[][] adjMat;
	private MyStack stack = new MyStack();
	//当前遍历的下标
	private int currentIndex;
	
	public Graph(int size) {
		vertex=new Vertex[size];
		adjMat=new int[size][size];
	}
	
	/**
	 * 向图中加入一个顶点
	 * @param v
	 */
	public void addVertex(Vertex v) {
		vertex[currentSize++]=v;
	}
	
	public void addEdge(String v1,String v2) {
		//找出两个顶点的下标
		int index1=0;
		for(int i=0;i<vertex.length;i++) {
			if(vertex[i].getValue().equals(v1)) {
				index1=i;
				break;
			}
		}
		int index2=0;
		for(int i=0;i<vertex.length;i++) {
			if(vertex[i].getValue().equals(v2)) {
				index2=i;
				break;
			}
		}
		adjMat[index1][index2]=1;
		adjMat[index2][index1]=1;
	}
	
	/**
	 * 深度优先搜索算法遍历图
	 */
	public void dfs() {
		//把第0个顶点标记为已访问状态
		vertex[0].visited=true;
		//把第0个顶点的下标。
		stack.push(0);
		//打印顶点的值
		System.out.println(vertex[0].getValue());
		//遍历
		out:while(!stack.isEmpty()) {
			for(int i=currentIndex+1;i<vertex.length;i++) {
				//如果和下一个遍历的元素是通的
				if(adjMat[currentIndex][i]==1&&vertex[i].visited==false) {
					//把下一个元素压入栈中
					stack.push(i);
					vertex[i].visited=true;
					System.out.println(vertex[i].getValue());
					continue out;
				}
			}
			//弹出栈顶元素
			stack.pop();
			//修改当前位置为栈顶元素的位置
			if(!stack.isEmpty()) {
				currentIndex=stack.peek();
			}
		}
	}
	
}

package demo14;

import java.util.Arrays;

public class TestGraph {

	public static void main(String[] args) {
		Vertex v1 = new Vertex("A");
		Vertex v2 = new Vertex("B");
		Vertex v3 = new Vertex("C");
		Vertex v4 = new Vertex("D");
		Vertex v5 = new Vertex("E");
		Graph g = new Graph(5);
		g.addVertex(v1);
		g.addVertex(v2);
		g.addVertex(v3);
		g.addVertex(v4);
		g.addVertex(v5);
		
		//增加边
		g.addEdge("A", "C");
		g.addEdge("B", "C");
		g.addEdge("A", "B");
		g.addEdge("B", "D");
		g.addEdge("B", "E");
		
		for(int[] a:g.adjMat) {
			System.out.println(Arrays.toString(a));
		}
		//深度优先遍历
		g.dfs();
	}
	
}

package demo14;

/**
 * 顶点类
 * @author Richard
 */
public class Vertex {

	private String value;
	public boolean visited;

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public Vertex(String value) {
		super();
		this.value = value;
	}

	@Override
	public String toString() {
		return value;
	}

}

图的遍历原理

深度优先遍历,使用的是栈
广度优先遍历,使用的是队列
在这里插入图片描述

在这里插入图片描述

图的遍历代码实现

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C语言中,哈希表是一种常用的数据结构,用于存储键值对。遍历哈希表可以通过以下步骤实现: 1. 创建一个指向哈希表的指针,并初始化为哈希表的起始位置。 2. 使用循环遍历哈希表的每个桶(bucket)或槽(slot),直到遍历完所有的桶。 3. 在每个桶中,遍历链表或其他数据结构,以访问存储在哈希表中的键值对。 4. 对于每个键值对,可以执行相应的操作,如打印键和值。 5. 继续遍历下一个桶,直到遍历完整个哈希表。 以下是一个示例代码,演示了如何遍历一个简单的哈希表: ```c #include <stdio.h> #define SIZE 10 // 定义哈希表节点结构 typedef struct Node { int key; int value; struct Node* next; } Node; // 创建哈希表 Node* createHashTable() { Node* hashTable[SIZE] = { NULL }; return hashTable; } // 向哈希表中插入键值对 void insert(Node** hashTable, int key, int value) { // 计算哈希值 int index = key % SIZE; // 创建新节点 Node* newNode = (Node*)malloc(sizeof(Node)); newNode->key = key; newNode->value = value; newNode->next = NULL; // 插入节点到哈希表中 if (hashTable[index] == NULL) { hashTable[index] = newNode; } else { Node* temp = hashTable[index]; while (temp->next != NULL) { temp = temp->next; } temp->next = newNode; } } // 遍历哈希表 void traverseHashTable(Node** hashTable) { for (int i = 0; i < SIZE; i++) { Node* temp = hashTable[i]; while (temp != NULL) { printf("Key: %d, Value: %d\n", temp->key, temp->value); temp = temp->next; } } } int main() { Node** hashTable = createHashTable(); // 向哈希表中插入键值对 insert(hashTable, 1, 10); insert(hashTable, 2, 20); insert(hashTable, 11, 30); // 遍历哈希表并打印键值对 traverseHashTable(hashTable); return 0; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值