數據結構與算法實例分析——復數實現
數據結構與算法要求:
學會分析研究計算機加工處理的對象的特征,以便為應用涉及的對象選擇適當的邏輯結構,存儲結構以及相應的算法,並初步掌握算法的時間分析以及空間分析技術
數據結構:是相互之間存在一種或多種特定關系的數據元素的集合。在任何問題中,數據元素都不是孤立存在的,而是在他們之間存在着某種關系,這種數據元素相互之間的關系稱為結構。根據數據元素之間的不同特性,通常有下列四種基本結構
①集合——結構中的數據元素之間除了"同屬於一個聚合"的關系外,別無其他關系②線性結構——結構中的數據元素之間存在一個對一個的關系;③樹形結構——結構中的數據元素之間存在一個對多個的關系;④圖狀結構或網狀結構——結構中的數據元素之間存在多個對多個的關系
算法和算法分析:
算法是對特定問題求解步驟的一種描述,它是指令的有限序列,其中每一條指令表示一個或多個操作;此外,一個算法還具有下列5個重要特性:
★ 有窮性:一個算法必須總是(對任何合法的輸入值)在執行有窮步之后結束,且每一步都可在有窮時間內完成
★ 確定性:算法中每一條指令必須有確切的含義並且在任何條件下,算法只有唯一的一條執行路徑,即對於相同的輸入只能得出相同的輸出。
★ 可行性:一個算法是能行的,即算法中描述的操作都是可以通過已經實現的基本運算執行有限次來實現的。
★ 輸入:一個算法有零個或多個的輸入,這些輸入取自於某個特定的對象的集合
★ 輸出:一個算法有一個或多個的輸出,這些輸出是同輸入有着某些特定關系的量
復數四則運算
一.復數基本操作
1.復數的四則運算操作:(z1=a(實部)+b(虛部)i,z2=c+di)
z1+z2=(a+c)+(c+d)i;
z1-z2=(a-c)+(c-d)i;
z1*z2=(ac-bd)+(ad+bc)i;
z1/z2=(ac+bd)/(c2+d2)+(bc-ad)/(c2+d2)i;
2.復數的基本操作
<建造空間:struct complex_t *complex_init();
釋放已經開辟內存空間:void complex_free(struct complex_t *z);
訪問指定內存空間(實部):double complex_get_real(struct complex_t *z);
訪問指定內存空間(虛部):double complex_get_imag(struct complex_t *z);
修改指定內存參數(實部):void complex_set_real(struct complex_t *z,double real);
修改指定內存參數(虛部):void complex_set_imag(struct complex_t *z,double imag);
復數相加操作:void complex_additive(struct complex_t *z1,struct complex_t *z2,struct complex_t *z3);
復數相減操作:void complex_subtract(struct complex_t *z1,struct complex_t *z2,struct complex_t *z3);
復數相乘操作:void complex_multiply(struct complex_t *z1,struct complex_t *z2,struct complex_t *z3);
復數相除操作:void complex_devide(struct complex_t *z1,struct complex_t *z2,struct complex_t *z3);
二.復數的存儲結構
1.結構A:
2.結構B:
3.結構C:
4.結構D:
complex_t.h
#ifndef __COMPLEX_T_H__
#define __COMPLEX_T_H__
struct complex_t;
//初始化內存空間,返回指向該內存空間的指針變量
struct complex_t *complex_init();
//釋放內存
void complex_free(struct complex_t *z);
//得到復數的實部元素
double complex_get_real(struct complex_t *z);
//得到復數的虛部元素
double complex_get_imag(struct complex_t *z);
//設置復數的實部元素
void complex_set_real(struct complex_t *z,double real);
//設置復數的虛部元素
void complex_set_imag(struct complex_t *z,double imag);
//將z1、z2指向的已定義的存儲結構中的復數實部取出相加放入z3指向的存儲空間的實部位置
void complex_addition(struct complex_t *z3,struct complex_t *z1,struct complex_t *z2);
//將z1、z2指向的已定義的存儲結構中的復數實部取出相減放入z3指向的存儲空間的實部位置
void complex_subtract(struct complex_t *z3,struct complex_t *z1,struct complex_t *z2);
//將z1、z2指向的已定義的存儲結構中的復數實部取出相乘放入z3指向的存儲空間的實部位置
void complex_multiply(struct complex_t *z3,struct complex_t *z1,struct complex_t *z2);
////將z1、z2指向的已定義的存儲結構中的復數實部取出相除放入z3指向的存儲空間的實部位置
void complex_devide(struct complex_t *z3,struct complex_t *z1,struct complex_t *z2);
#endif
main.c
//進行復數的四則運算
#include <stdio.h>
#include <stdlib.h>
#include "complex_t.h"
int main(int argc, char *argv[]) {
//定義三個結構體指針變量,用來分別指向三個相同的將要定義的存儲空間
struct complex_t *z1=NULL;
struct complex_t *z2=NULL;
struct complex_t *z3=NULL;
z1=complex_init();
//將3.32存儲到指針變量z1指向的內存空間的實部位置
complex_set_real(z1,3.32);
//將-5.12存儲到指針變量z1指向的內存空間的虛部位置
complex_set_imag(z1,-5.12);
//將z1指向的存儲結構中的復數實部和虛部取出
printf("z1=%.2f+%.2fi\n",complex_get_real(z1),complex_get_imag(z1));
z2=complex_init();
complex_set_real(z2,9.21);
complex_set_imag(z2,0.54);
printf("z2=%.2f+%.2fi\n",complex_get_real(z2),complex_get_imag(z2));
z3=complex_init();
//將指針變量z1,z2和指向存放結果結構的z3傳入complex_addition函數相加(z1指向的存儲結構中復數實部和z2指向的存儲結構中復數實部相加存入z3指向的存儲結構的實部中……)
complex_addition(z3,z1,z2);
printf("z1+z2=%.2f+%.2fi\n",complex_get_real(z3),complex_get_imag(z3));
complex_subtract(z3,z1,z2);
printf("z1_z2=%.2f+%.2fi\n",complex_get_real(z3),complex_get_imag(z3));
complex_multiply(z3,z1,z2);
printf("z1*z2=%.2f+%.2fi\n",complex_get_real(z3),complex_get_imag(z3));
complex_devide(z3,z1,z2);
printf("z1/z2=%.2f+%.2fi\n",complex_get_real(z3),complex_get_imag(z3));
complex_free(z1);
complex_free(z2);
complex_free(z3);
return 0;
}
complex_t.c
結構A
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "complex_t.h"
//定義結構體存放復數的實部和虛部
struct complex_t{
double real;
double imag;
};
//開辟內存空間用來存放復數的實部和虛部,返回指向該內存空間的指針變量
struct complex_t *complex_init()
{
struct complex_t *z=NULL;
//開辟結構體類型complex_t大小的空間,將malloc()返回的指向已開辟空間的指針強制類型裝換賦給z
z=(struct complex_t *)malloc(sizeof(struct complex_t));//分配內存空間
if(z==NULL) return NULL;
assert(z!=NULL);
z->imag=0.0f;//初始化
z->real=0.0f;
return z;
}
void complex_free(struct complex_t *z)
{
assert(z!=NULL);
free(z);
}
//根據結構體指針變量z,取出復數的實部部分
double complex_get_real(struct complex_t *z)
{
assert(z!=NULL);
return z->real;
}
//根據結構體指針變量z,取出復數的虛部部分
double complex_get_imag(struct complex_t *z)
{
assert(z!=NULL);
return z->imag;
}
//根據結構體指針變量z,存儲復數的實部部分
void complex_set_real(struct complex_t *z,double real)
{
assert(z!=NULL);
z->real=real;
}
//根據結構體指針變量z,存儲復數的實部部分
void complex_set_imag(struct complex_t *z,double imag)
{
assert(z!=NULL);
z->imag=imag;
}
//將z1和z2指向的內存空間中的復數實部和虛部分別取出相加,結果分別存儲到z3指向的內存空間存儲復數實部和虛部的位置
void complex_addition(struct complex_t *z3,struct complex_t *z1,struct complex_t *z2)
{
assert(z1!=NULL);
assert(z2!=NULL);
assert(z3!=NULL);
double a,b,c,d;
a=z1->real;
b=z1->imag;
c=z2->real;
d=z2->imag;
z3->real=a+c;
z3->imag=b+d;
}
//將z1和z2指向的內存空間中的復數實部和虛部分別取出相減,結果分別存儲到z3指向的內存空間存儲復數實部和虛部的位置
void complex_subtract(struct complex_t *z3,struct complex_t *z1,struct complex_t *z2)
{
assert(z1!=NULL);
assert(z2!=NULL);
assert(z3!=NULL);
double a,b,c,d;
a=z1->real;
b=z1->imag;
c=z2->real;
d=z2->imag;
z3->real=a-c;
z3->imag=b-d;
}
////將z1和z2指向的內存空間中的復數實部和虛部分別取出相乘,結果分別存儲到z3指向的內存空間存儲復數實部和虛部的位置
void complex_multiply(struct complex_t *z3,struct complex_t *z1,struct complex_t *z2)
{
assert(z1!=NULL);
assert(z2!=NULL);
assert(z3!=NULL);
double a,b,c,d;
a=z1->real;
b=z1->imag;
c=z2->real;
d=z2->imag;
z3->real=a*c+b*d;
z3->imag=b*c-a*d;
}
//將z1和z2指向的內存空間中的復數實部和虛部分別取出相除,結果分別存儲到z3指向的內存空間存儲復數實部和虛部的位置
void complex_devide(struct complex_t *z3,struct complex_t *z1,struct complex_t *z2)
{
assert(z1!=NULL);
assert(z2!=NULL);
assert(z3!=NULL);
double a,b,c,d;
a=z1->real;
b=z1->imag;
c=z2->real;
d=z2->imag;
z3->real=(a*c-b*d)/(c*c+d*d);
z3->imag=(b*c+a*d)/(c*c+d*d);
}
結構B
//數組名為數組的首地址
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "complex_t.h"
//定義結構體用來存放數組的首地址(數組中存放復數的實部和虛部)
struct complex_t{
double *data;
};
//初始化存儲結構,返回指向該存儲結構的指針變量
struct complex_t *complex_init()
{
struct complex_t *z=NULL;
z=(struct complex_t *)malloc(sizeof(struct complex_t));
if(z==NULL) return NULL;
assert(z!=NULL);
z->data=NULL;
z->data=(int *)malloc(sizeof(int)*2);
if(z->data==NULL){
free(z);
return NULL;
}
assert(z!=NULL);
z->data[1]=0.0f;
z->data[2]=0.0f;
return z;
}
void complex_free(struct complex_t *z)
{
assert(z!=NULL);
assert(z->data!=NULL);
free(z->data);
free(z);
}
double complex_get_real(struct complex_t *z)
{
//數組名為數組的首地址
assert(z!=NULL);
assert(z->data!=NULL);
return z->data[1];
}
double complex_get_imag(struct complex_t *z)
{
assert(z!=NULL);
assert(z->data!=NULL);
return z->data[2];
}
void complex_set_real(struct complex_t *z,double real)
{
assert(z!=NULL);
assert(z->data!=NULL);
z->data[1]=real;
}
void complex_set_imag(struct complex_t *z,double imag)
{
assert(z!=NULL);
assert(z->data!=NULL);
z->data[2]=imag;
}
//將z1和z2指向的內存空間中的復數實部和虛部分別取出相加,結果分別存儲到z3指向的內存空間存儲復數實部和虛部的位置
void complex_addition(struct complex_t *z3,struct complex_t *z1,struct complex_t *z2)
{
assert(z1!=NULL);
assert(z2!=NULL);
assert(z3!=NULL);
double a,b,c,d;
a=z1->data[1];
b=z1->data[2];
c=z2->data[1];
d=z2->data[2];
z3->data[1]=a+c;
z3->data[2]=b+d;
}
//將z1和z2指向的內存空間中的復數實部和虛部分別取出相減,結果分別存儲到z3指向的內存空間存儲復數實部和虛部的位置
void complex_subtract(struct complex_t *z3,struct complex_t *z1,struct complex_t *z2)
{
assert(z1!=NULL);
assert(z2!=NULL);
assert(z3!=NULL);
double a,b,c,d;
a=z1->data[1];
b=z1->data[2];
c=z2->data[1];
d=z2->data[2];
z3->data[1]=a-c;
z3->data[2]=b-d;
}
//將z1和z2指向的內存空間中的復數實部和虛部分別取出相乘,結果分別存儲到z3指向的內存空間存儲復數實部和虛部的位置
void complex_multiply(struct complex_t *z3,struct complex_t *z1,struct complex_t *z2)
{
assert(z1!=NULL);
assert(z2!=NULL);
assert(z3!=NULL);
double a,b,c,d;
a=z1->data[1];
b=z1->data[2];
c=z2->data[1];
d=z2->data[2];
z3->data[1]=a*c+b*d;
z3->data[2]=b*c-a*d;
}
//將z1和z2指向的內存空間中的復數實部和虛部分別取出相除,結果分別存儲到z3指向的內存空間存儲復數實部和虛部的位置
void complex_devide(struct complex_t *z3,struct complex_t *z1,struct complex_t *z2)
{
assert(z1!=NULL);
assert(z2!=NULL);
assert(z3!=NULL);
double a,b,c,d;
a=z1->data[1];
b=z1->data[2];
c=z2->data[1];
d=z2->data[2];
z3->data[1]=(a*c-b*d)/(c*c+d*d);
z3->data[2]=(b*c+a*d)/(c*c+d*d);
}
結構C:
//除在指針定義處外,*(變量名)均表示指針變量指向的值
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "complex_t.h"
//定義結構體作為一級結構,指針變量real存放復數實部地址和指針變量imag存放虛部的地址
struct complex_t{
double *real;
double *imag;
};
struct complex_t *complex_init()
{
struct complex_t *z=NULL;
z=(struct complex_t *)malloc(sizeof(struct complex_t));
if(z==NULL) return NULL;
assert(z!=NULL);
z->real=NULL;
z->real=(double *)malloc(sizeof(double));
if(z->real==NULL) {
free(z);
return NULL;
}
assert(z->real!=NULL);
z->imag=NULL;
z->imag=(double *)malloc(sizeof(double));
if(z->imag==NULL){
free(z);
return NULL;
}
//將初值賦給z->real的值
*(z->real)=0.0f;
*(z->imag)=0.0f;
return z;
}
void complex_free(struct complex_t *z)
{
assert(z->real!=NULL);
assert(z->imag!=NULL);
assert(z!=NULL);
free(z);
free(z->real);
free(z->imag);
}
double complex_get_real(struct complex_t *z)
{
assert(z->real!=NULL);
assert(z->imag!=NULL);
assert(z!=NULL);
//返回z->real的值
return *(z->real);
}
double complex_get_imag(struct complex_t *z)
{
assert(z->real!=NULL);
assert(z->imag!=NULL);
assert(z!=NULL);
//返回z->imag的值
return *(z->imag);
}
void complex_set_real(struct complex_t *z,double real)
{
assert(z->real!=NULL);
assert(z->imag!=NULL);
assert(z!=NULL);
*(z->real)=real;
}
void complex_set_imag(struct complex_t *z,double imag)
{
assert(z->real!=NULL);
assert(z->imag!=NULL);
assert(z!=NULL);
*(z->imag)=imag;
}
//將z1和z2指向的內存空間中的復數實部和虛部分別取出相加,結果分別存儲到z3指向的內存空間存儲復數實部和虛部的位置
void complex_addition(struct complex_t *z3,struct complex_t *z1,struct complex_t *z2)
{
assert(z1!=NULL);
assert(z2!=NULL);
assert(z3!=NULL);
double a,b,c,d;
a=*(z1->real);
b=*(z1->imag);
c=*(z2->real);
d=*(z2->imag);
*(z3->real)=a+c;
*(z3->imag)=b+d;
}
//將z1和z2指向的內存空間中的復數實部和虛部分別取出相減,結果分別存儲到z3指向的內存空間存儲復數實部和虛部的位置
void complex_subtract(struct complex_t *z3,struct complex_t *z1,struct complex_t *z2)
{
assert(z1!=NULL);
assert(z2!=NULL);
assert(z3!=NULL);
double a,b,c,d;
a=*(z1->real);
b=*(z1->imag);
c=*(z2->real);
d=*(z2->imag);
*(z3->real)=a-c;
*(z3->imag)=b-d;
}
//將z1和z2指向的內存空間中的復數實部和虛部分別取出相乘,結果分別存儲到z3指向的內存空間存儲復數實部和虛部的位置
void complex_multiply(struct complex_t *z3,struct complex_t *z1,struct complex_t *z2)
{
assert(z1!=NULL);
assert(z2!=NULL);
assert(z3!=NULL);
double a,b,c,d;
a=*(z1->real);
b=*(z1->imag);
c=*(z2->real);
d=*(z2->imag);
*(z3->real)=a*c+b*d;
*(z3->imag)=b*c-a*d;
}
//將z1和z2指向的內存空間中的復數實部和虛部分別取出相除,結果分別存儲到z3指向的內存空間存儲復數實部和虛部的位置
void complex_devide(struct complex_t *z3,struct complex_t *z1,struct complex_t *z2)
{
assert(z1!=NULL);
assert(z2!=NULL);
assert(z3!=NULL);
double a,b,c,d;
a=*(z1->real);
b=*(z1->imag);
c=*(z2->real);
d=*(z2->imag);
*(z3->real)=(a*c-b*d)/(c*c+d*d);
*(z3->imag)=(b*c+a*d)/(c*c+d*d);
}
結構D:
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "complex_t.h"
//定義結構體類型complex_node作為數據節點類型,data存放要存儲的數值,指針變量next指向下一個complex_node類型的數據節點
struct complex_node{
double data;
struct complex_node *next;
};
//定義complex_t結構體類型,其中指針變量head指向coplex_node類型的結構體
struct complex_t{
struct complex_node *head;
};
struct complex_t *complex_init()
{
struct complex_t *z=NULL;
z=(struct complex_t *)malloc(sizeof(struct complex_t));
if(z==NULL) return NULL;
assert(z!=NULL);
z->head=NULL;
z->head=(struct complex_node *)malloc(sizeof(struct complex_node));
if(z->head==NULL){
free(z);
return NULL;
}
assert(z->head!=NULL);
z->head->data=0.0f;
z->head->next=NULL;
z->head->next=(struct complex_node *)malloc(sizeof(struct complex_node));
if(z->head->next==NULL){
free(z->head);
free(z);
return NULL;
}
assert(z->head->next!=NULL);
z->head->next->data=0.0f;
z->head->next->next=NULL;
return z;
}
void complex_free(struct complex_t *z)
{
assert(z->head->next!=NULL);
assert(z->head!=NULL);
assert(z!=NULL);
free(z->head->next);
free(z->head);
free(z);
}
double complex_get_real(struct complex_t *z)
{
assert(z->head->next!=NULL);
assert(z->head!=NULL);
assert(z!=NULL);
return z->head->data;
}
double complex_get_imag(struct complex_t *z)
{
assert(z->head->next!=NULL);
assert(z->head!=NULL);
assert(z!=NULL);
return z->head->next->data;
}
void complex_set_real(struct complex_t *z,double real)
{
assert(z->head->next!=NULL);
assert(z->head!=NULL);
assert(z!=NULL);
z->head->data=real;
}
void complex_set_imag(struct complex_t *z,double imag)
{
assert(z->head->next!=NULL);
assert(z->head!=NULL);
assert(z!=NULL);
z->head->next->data=imag;
}
//將z1和z2指向的內存空間中的復數實部和虛部分別取出相減,結果分別存儲到z3指向的內存空間存儲復數實部和虛部的位置
void complex_addition(struct complex_t *z3,struct complex_t *z1,struct complex_t *z2)
{
assert(z1!=NULL);
assert(z2!=NULL);
assert(z3!=NULL);
double a,b,c,d;
a=z1->head->data;
b=z1->head->next->data;
c=z2->head->data;
d=z2->head->next->data;
z3->head->data=a+c;
z3->head->next->data=b+d;
}
void complex_subtract(struct complex_t *z3,struct complex_t *z1,struct complex_t *z2)
{
assert(z1!=NULL);
assert(z2!=NULL);
assert(z3!=NULL);
double a,b,c,d;
a=z1->head->data;
b=z1->head->next->data;
c=z2->head->data;
d=z2->head->next->data;
z3->head->data=a-c;
z3->head->next->data=b-d;
}
void complex_multiply(struct complex_t *z3,struct complex_t *z1,struct complex_t *z2)
{
assert(z1!=NULL);
assert(z2!=NULL);
assert(z3!=NULL);
double a,b,c,d;
a=z1->head->data;
b=z1->head->next->data;
c=z2->head->data;
d=z2->head->next->data;
z3->head->data=a*c+b*d;
z3->head->next->data=b*c-a*d;
}
void complex_devide(struct complex_t *z3,struct complex_t *z1,struct complex_t *z2)
{
assert(z1!=NULL);
assert(z2!=NULL);
assert(z3!=NULL);
double a,b,c,d;
a=z1->head->data;
b=z1->head->next->data;
c=z2->head->data;
d=z2->head->next->data;
z3->head->data=(a*c-b*d)/(c*c+d*d);
z3->head->next->data=(b*c+a*d)/(c*c+d*d);
}
### 三.編譯結果
