#基本的なデータ構造とアルゴリズム(線形テーブル)

データ構造とアルゴリズム(線形テーブル)


線形テーブル(線形ストレージ構造)

ここに写真の説明を挿入

データをつなぎ合わせて物理アドレスに保存することです。「1対1」の関係にあるデータは、物理空間に「線形」に格納されます。この格納構造は、線形格納構造(線形テーブルと呼ばれます)と呼ばれます。
ここに写真の説明を挿入

シーケンシャルストレージ構造

図3aに示すように、データは連続する物理アドレスに格納されます。シーケンステーブルにデータが格納されている場合、すべてのデータは連続したアドレスに格納され、間にギャップはありません。

シーケンステーブルの初期化

シーケンステーブルを使用する前に、スペースを申請し、要求されたストレージ容量とデータ要素の数をテーブルに記録する必要があります。

  • 線形テーブルを定義し、その中に要素を配置します
#include <stdio.h>
#include <stdlib.h>

typedef struct Table{
    
    
	int * head;
	int length;
	int size;
}table;

table initTable(){
    
    
	table t;
	t.head=(int*)malloc(5*sizeof(int));
	if(!t.head){
    
    
		printf("初始化失败");
		exit(0); 
	}else{
    
    
		printf("初始化成功!");
	}
	t.length=0;
	t.size=5;
	return t;
}

int main(int argc, char *argv[]) {
    
    
	table t=initTable();
	printf("表的大小为%d",t.length);
	int i;
	for(i=0;i<5;i++){
    
    
		t.head[i]=i;
		t.length++;
	}
	for(i=0;i<t.size;i++){
    
    
		printf("\n");
		printf("%d",t.head[i]);
	}
	return 0;
}
シーケンステーブル挿入要素
  • ヘッダーに挿入
  • 表の最後に挿入します
  • 途中で

要素を挿入するには、挿入する位置の要素とそれに続く要素全体を後方に移動し、要素を空の位置に追加するという2つの操作を実行します。

// 在指定位置插入元素
table addElement(table t,int element,int pos){
    
    
	// 插在表尾部 
	if(pos==t.length){
    
    
		// 重新申请大小 
		t.head=(int*)realloc(t.head,(t.size+1)*sizeof(int));
		if(!t.head){
    
    
			printf("扩容失败!");
			return t; 
		}
		t.size+=1;		
	} 
	if(pos>t.size+1 || pos<1){
    
    
		printf("插入位置错误");
		exit(0); 
	}
	// 将插入位置以及之后的元素向后移动
	int i; 
	for(i=t.length-1;i>=pos-1;i--){
    
    
		t.head[i+1]=t.head[i];
	} 
	// 将元素放到空的位置
	t.head[pos-1]=element;
	t.length++;
	return t;
	
} 
シーケンステーブル削除要素

指定された削除位置の後の要素を1つ前方に移動するだけで、値として指定された線形テーブルが削除されます。

table delTable(table t, int add) {
    
    
    int i;
    if (add > t.length || add < 1) {
    
    
        printf("被删除元素的位置有误");
        exit(0);
    }
    //删除操作
    for (i = add; i < t.length; i++) {
    
    
        t.head[i - 1] = t.head[i];
    }
    t.length--;
    return t;
}
要素を見つける
  • ターゲット要素を見つけます。

  • 要素の値を直接変更します。

//更改函数,其中,elem为要更改的元素,newElem为新的数据元素
table amendTable(table t, int elem, int newElem) {
    
    
    int add = selectTable(t, elem);
    t.head[add - 1] = newElem;//由于返回的是元素在顺序表中的位置,所以-1就是该元素在数组中的下标
    return t;
}

チェーン収納構造

図3bに示すように、番号データは物理アドレスに格納されますが、データの順序は変更されず、データ間の論理的な順序は1行で維持されます。

チェーンストレージの特徴

データ要素を格納するために、任意のストレージユニットのグループが使用されます。このストレージユニットのグループは、連続的または非連続的です。


リンクリスト

リンクリストの概念
  • データドメイン:データ要素情報を格納するドメインは、データドメインと呼ばれます。
  • ポインタフィールド:直後の後続の位置を格納するフィールドは、ポインタフィールドと呼ばれます。
  • n個のノードがリンクリストにリンクされます。これは線形リストのチェーンストレージ構造です。

単一のリスト

リンクリストの各ノードにはポインタフィールドが1つだけ含まれ、ポインタフィールドに格納されている情報はチェーンと呼ばれ、チェーンの各ノードには1つしかありません。リンクリストの最初のノードの保存場所はヘッドポインタと呼ばれます。リンクリストにヘッドノードがある場合、ヘッドポインタはヘッドノードのデータフィールドへのポインタです。

ノードの定義
// 定义链表 
typedef struct Node{
    
    
	// 数据域 
	Item item;
	// 指向后继节点的指针 
	struct Node *next; 
}Node,*List; 
データ構造
/*数据域的数据结构体*/
typedef struct Contet{
    
    
	int id;
	char name[20];
}Item;
リンクリストを初期化する
// 初始化一个链表 
List init(){
    
    
	// 定义头节点 
	List head=(List)malloc(sizeof(Node));
	if(!head){
    
    
		printf("分配内存空间失败!");
		return 0;
	}else{
    
    
		printf("内存分配成功链表创建!"); 
		// 指针域为空 
		head->next=NULL;
		return head;
	} 
}
リンクリストにデータを追加する

ここに写真の説明を挿入

// 增加数据
void insert(List head){
    
    
	// 定义新的节点对象 
	Item item;
	printf("输入编号:");
	scanf("%d",&item.id);
	
	printf("输入姓名:");
	scanf("%s",&item.name);
	
	// 清空缓冲区
	getchar();
	
	List p=(List)malloc(sizeof(Node));
	p->item=item;
	p->next=head->next;
	head->next=p;
} 
リンクリストからデータを削除する

ここに写真の説明を挿入

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

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

/*数据域的数据结构体*/
typedef struct Contet{
    
    
	int id;
	char name[20];
}Item;

// 定义链表 
typedef struct Node{
    
    
	// 数据域 
	Item item;
	// 指向后继节点的指针 
	struct Node *next; 
}Node,*List; 

// 初始化一个链表 
List init(){
    
    
	// 定义头节点 
	List head=(List)malloc(sizeof(Node));
	if(!head){
    
    
		printf("分配内存空间失败!");
		return 0;
	}else{
    
    
		printf("内存分配成功链表创建!"); 
		printf("\n");
		// 指针域为空 
		head->next=NULL;
		return head;
	} 
}

// 增加数据
void insert(List head){
    
    
	// 定义新的节点对象 
	Item item;
	printf("输入编号:");
	scanf("%d",&item.id);
	
	printf("输入姓名:");
	scanf("%s",&item.name);
	
	// 清空缓冲区
	getchar();
	
	List p=(List)malloc(sizeof(Node));
	p->item=item;
	p->next=head->next;
	head->next=p;
} 

int main(int argc, char *argv[]) {
    
    
	
	// 初始化链表 
	List head=init();

	int n;
	printf("输入你想录入数据的个数:");
	scanf("%d",&n);
	
	int i; 
	for(i=0;i<n;i++){
    
    
		insert(head);
	}
	
	Item *p;
	p=head->next;

	printf("当前人编号:%d",p->id);
	printf("当前人姓名:%s",p->name);
	return 0;
}

アレイ

javaでは、配列が作成されると、連続するメモリがメモリに分割され、データが入力されると、データはこの連続するメモリに順番に格納されます。アレイ内のデータを読み取る必要がある場合は、アレイ内のインデックスを指定する必要があります。その後、アレイはインデックスに従ってメモリ内のデータを取り出し、読み取りプログラムに返します。Javaでは、すべてのデータを配列に格納できるわけではなく、同じタイプのデータのみを一緒に配列に格納できます。

ここに写真の説明を挿入

特徴

  • 保存順序は順番に保存され、データを保存するためのメモリも連続しています。
  • データのアドレス指定と読み取りは簡単ですが、挿入と削除はより困難です。

応用

動的配列ArrayList
  • ArratListは動的配列と同等であり、拡張をサポートします。
  • アレイを定義するときは、連続したメモリスペースを割り当てる必要があるため、事前にサイズを指定する必要があります。保存するデータがサイズよりも大きい場合は、より大きなスペースを割り当て、元のスペースをコピーして、新しいものを挿入する必要があります。要素。
  • ArrayListでは、スペースが十分でない場合、元のサイズの1.5倍に自動的に拡張されます。
静的配列
  • Javaで配列を定義するには、次の2つの構文があります
    。typearrayName[];
    type [] arrayName;

キュー

キューは先着順のデータ構造であり、配列とリンクリストもキューを生成できます。データがキューに入ると、最初に入力され、次に下に入力され、次に上に入力されますが、キューを離れるときは、最初に下から出力され、次に上のデータ、最後に入力されて最後に出力されます。

@Test
public void test(){
    
    
    Queue<Integer> queue=new LinkedList<>();
    queue.offer(1);
    queue.offer(2);
    queue.offer(3);
    queue.offer(4);
    queue.offer(5);
    queue.offer(6);
    queue.forEach(System.out::println);
}
ブロッキングキュー
同時キュー

スタック

スタックはファーストインラストアウトのデータ構造であり、アレイとリンクリストの両方でスタックを生成できます。データがスタックに入ると、ルールに従ってスタックの一番下にプッシュされ、再度入力されたデータは最初のデータの上にプッシュされます。スタック内のデータをフェッチするときは、最上位のデータが最初にフェッチされるため、最初から最後までです。

@Test
public void test1(){
    
    
    Stack<Integer> stack=new Stack<>();
    stack.push(1);
    stack.push(2);
    stack.push(4);
    stack.forEach(System.out::println);
}

つづく

おすすめ

転載: blog.csdn.net/qq_37248504/article/details/109479766